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 -q
instead ofgrep -c
, it will exit with0
on 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