grep PATTERN 文件,当模式存在时 gzip,否则不执行任何操作

grep PATTERN 文件,当模式存在时 gzip,否则不执行任何操作

设置:Linux GNU bash,版本 4.3

if grep -c PATTERN $sourcefile
then
     grep PATTERN $sourcefile | gzip  > compressedfile.gz
fi

我想防止必须两次访问源文件。

我怎样才能做到这一点?

答案1

grep 'PATTERN' "$sourcefile" >compressedfile
if [ -s compressedfile ]; then
    gzip -f compressedfile
else
    rm -f compressedfile
fi

-s如果给定的文件名存在并且它引用的文件的大小大于零,则测试为真。该文件将存在(如果该文件尚不存在,则重定向始终会创建该文件),并且如果grep.

即使文件会增长(如果文件一开始很小就会这样做),该-f标志也会强制压缩。gzip

grep几乎相同的事情(因为如果 发生某种读/写错误,它不会压缩输出grep),但使用 的退出状态grep

if grep 'PATTERN' "$sourcefile" >compressedfile; then
    gzip -f compressedfile
else
    rm -f compressedfile
fi

要不就

grep 'PATTERN' "$sourcefile" >compressedfile && gzip -f compressedfile
rm -f compressedfile

这里,rm无论如何都会尝试删除未压缩的文件,但由于我们使用的是rm -f,因此如果文件不存在,则不会报告错误(如果gzip压缩了文件,则不会存在)。


在最一般的情况下,我建议不要将结果存储grep在变量中,因为这可能会返回千兆字节的数据(我们不知道这一点)。

答案2

您可以首先将 的结果分配grep给变量。然后您可以检查退出代码,如注释中@Mark建议的那样,或者检查结果是否为空字符串,如下所示:

foo=$(grep $PATTERN $sourcefile)
if [ ! -z "$foo" ]
then
        echo "$foo" | gzip > compressedfile.gz
fi

或者,作为一句:

foo=$(grep $PATTERN $sourcefile); [ -z "$foo" ] || echo "$foo" | gzip > compressedfile.gz

相关内容