Setup: Linux GNU bash, version 4.3
if grep -c PATTERN $sourcefile
then
grep PATTERN $sourcefile | gzip > compressedfile.gz
fi
I want to prevent having to access the sourcefile twice.
How can i achieve this?
Setup: Linux GNU bash, version 4.3
if grep -c PATTERN $sourcefile
then
grep PATTERN $sourcefile | gzip > compressedfile.gz
fi
I want to prevent having to access the sourcefile twice.
How can i achieve this?
grep 'PATTERN' "$sourcefile" >compressedfile
if [ -s compressedfile ]; then
gzip -f compressedfile
else
rm -f compressedfile
fi
The -s test will be true if the given filename exists and if it refers to a file whose size is greater than zero. The file will exist (a redirection always creates the file if it doesn't already exist) and the size will be greater than zero if there was any result from the grep.
The -f flag to gzip forces compression even if the file would grow (which it would do if it's tiny to start with).
The same thing, almost (since it won't compress the grep output if some sort of read/write error occurs for grep), but using the exit status of grep:
if grep 'PATTERN' "$sourcefile" >compressedfile; then
gzip -f compressedfile
else
rm -f compressedfile
fi
or just
grep 'PATTERN' "$sourcefile" >compressedfile && gzip -f compressedfile
rm -f compressedfile
Here, rm will try to remove the uncompressed file regardless, but since we're using rm -f, no error will be reported if the file does not exist (it won't exist if gzip has compressed it).
In the most general case, I'd advise against storing the result of grep in a variable as this may return gigabytes of data (we don't know this).
You could first assign the result of grep to a variable.
Then you can check the exit code, as suggested by @Mark in the comments, or check if the result is the empty string, as this:
foo=$(grep $PATTERN $sourcefile)
if [ ! -z "$foo" ]
then
echo "$foo" | gzip > compressedfile.gz
fi
or, as a one-liner:
foo=$(grep $PATTERN $sourcefile); [ -z "$foo" ] || echo "$foo" | gzip > compressedfile.gz
-s test), but we store the result of grep differently. Yours is perfectly fine if one knows there is not going to be much output from grep and if one is able to juggle $foo without letting the shell poke around in it.
– Kusalananda
Apr 26 '18 at 12:16
grep -qinstead ofgrep -c, it will exit with0on 1st match so you won't process the file twice (unless you only have one match which is on the last line). Related: Check if pipe is empty and run a command on the data if it isn't – don_crissti Apr 26 '18 at 10:18