How to check that a file has more than 1 line in a BASH conditional?
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
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.
if [ `wc -l file.txt | awk '{print $1}'` -ge "2" ]
...
You should always check what each subcommand returns. Command wc -l file.txt
returns output in the following format:
12 file.txt
You need first column - you can extract it with awk
or cut
or any other utility of your choice.
How about:
if read -r && read -r
then
echo "This has more than 1 line."
fi < file.txt
The -r
flag is needed to ensure line continuation characters don't fold two lines into one, which would cause the following file to report one line only:
This is a file with _two_ lines, \
but will be seen as one.