Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to check that a file has more than 1 line in a BASH conditional?

I need to check if a file has more than 1 line. I tried this:

if [ `wc -l file.txt` -ge "2" ] then     echo "This has more than 1 line." fi   if [ `wc -l file.txt` >= 2 ] then     echo "This has more than 1 line." fi 

These just report errors. How can I check if a file has more than 1 line in a BASH conditional?

like image 287
Village Avatar asked Sep 20 '14 08:09

Village


People also ask

How do I count lines in bash?

wc. The wc command is used to find the number of lines, characters, words, and bytes of a file. To find the number of lines using wc, we add the -l option. This will give us the total number of lines and the name of the file.

What is $@ in bash?

bash [filename] runs the commands saved in a file. $@ refers to all of a shell script's command-line arguments. $1 , $2 , etc., refer to the first command-line argument, the second command-line argument, etc. Place variables in quotes if the values might have spaces in them.

What does $_ mean in bash?

$_ (dollar underscore) is another special bash parameter and used to reference the absolute file name of the shell or bash script which is being executed as specified in the argument list. This bash parameter is also used to hold the name of mail file while checking emails.

What is Dash S in bash?

From man bash : -s If the -s option is present, or if no arguments remain after option processing, then commands are read from the standard input. This option allows the positional parameters to be set when invoking an interactive shell.


2 Answers

The command:

wc -l file.txt 

will generate output like:

42 file.txt 

with wc helpfully telling you the file name as well. It does this in case you're checking out a lot of files at once and want individual as well as total stats:

pax> wc -l *.txt  973 list_of_people_i_must_kill_if_i_find_out_i_have_cancer.txt    2 major_acheivements_of_my_life.txt  975 total 

You can stop wc from doing this by providing its data on standard input, so it doesn't know the file name:

if [[ $(wc -l <file.txt) -ge 2 ]] 

The following transcript shows this in action:

pax> wc -l qq.c 26 qq.c  pax> wc -l <qq.c 26 

As an aside, you'll notice I've also switched to using [[ ]] and $().

I prefer the former because it has less issues due to backward compatibility (mostly to do with with string splitting) and the latter because it's far easier to nest executables.

like image 117
paxdiablo Avatar answered Sep 20 '22 23:09

paxdiablo


A pure bash (≥4) possibility using mapfile:

#!/bin/bash  mapfile -n 2 < file.txt if ((${#MAPFILE[@]}>1)); then     echo "This file has more than 1 line." fi 

The mapfile builtin stores what it reads from stdin in an array (MAPFILE by default), one line per field. Using -n 2 makes it read at most two lines (for efficiency). After that, you only need to check whether the array MAPFILE has more that one field. This method is very efficient.

As a byproduct, the first line of the file is stored in ${MAPFILE[0]}, in case you need it. You'll find out that the trailing newline character is not trimmed. If you need to remove the trailing newline character, use the -t option:

mapfile -t -n 2 < file.txt 
like image 34
gniourf_gniourf Avatar answered Sep 17 '22 23:09

gniourf_gniourf