将 md5sum 输出通过管道传送到 grep,但 grep 会突出显示匹配项,而不是删除不匹配项

将 md5sum 输出通过管道传送到 grep,但 grep 会突出显示匹配项,而不是删除不匹配项

我从 a 下载了多个文件回购还有更多文件。每个文件的 md5sum 信息存储在名为 .md5sum 的单个文件中MD5SUMS

为了检查文件完整性,我md5sum -c MD5SUMS为文件中的所有文件生成了一个长输出MD5SUMS,当找不到文件(我没有下载)时抱怨并在找到文件并且 md5sum 信息匹配时说“确定”。

md5sum: gencode.v27.tRNAs.gtf.gz: No such file or directory
gencode.v27.tRNAs.gtf.gz: FAILED open or read
md5sum: GRCh38.p10.genome.fa.gz: No such file or directory
GRCh38.p10.genome.fa.gz: FAILED open or read
GRCh38.primary_assembly.genome.fa.gz: OK
md5sum: _README.TXT: No such file or directory
_README.TXT: FAILED open or read

我已经将其通过管道grep过滤掉“非正常”行,md5sum -c MD5SUMS | grep OK但是我仍然得到了完整的输出我得到了很长的输出:带有“没有这样的文件或目录”的行表示不存在的文件和“正常”短语md5sum 匹配的文件以红色突出显示。

md5sum: gencode.v27.polyAs.gff3.gz: No such file or directory
md5sum: gencode.v27.polyAs.gtf.gz: No such file or directory
gencode.v27.primary_assembly.annotation.gff3.gz: OK
md5sum: gencode.v27.transcripts.fa.gz: No such file or directory
md5sum: gencode.v27.primary_assembly.annotation.gtf.gz: OK

但是,当我使用中间文件存储输出md5sum然后存储grep该文件时,我最终会得到包含短语“OK”的行,如预期的那样。

md5sum -c MD5SUMS > test
grep "OK" test

gencode.v27.primary_assembly.annotation.gff3.gz: OK
gencode.v27.primary_assembly.annotation.gtf.gz: OK
GRCh38.primary_assembly.genome.fa.gz: OK

我无法理解这个问题,你能帮我弄清楚管道出了什么问题还是预期的行为?

答案1

您会看到md5sum因丢失文件而生成的错误消息。这些消息是在标准错误流上生成的,因为它永远是标准错误流输出流通过管道传递,错误消息grep根本不会受到命令的影响。

要将它们重定向开以便您根本看不到它们,请使用

md5sum -c MD5SUMS 2>/dev/null | grep OK

如果要将错误保存到日志文件(例如,以便稍后检查丢失的文件),请替换/dev/null为要写入错误的文件的名称。


位的解释2>/dev/null

一个命令在可能的两个单独的流上生成输出,标准输出流标准错误流。它们始终分配给“文件描述符”1 和 2。

标准输出流是命令的“普通输出”所在的位置,这可能会通过管道传输到其他命令,就像在您的示例中通过管道传输到grep.

标准错误流是“诊断消息”所在的位置(这通常意味着“错误”),这可以不是通过管道传输到另一个命令,通常直接进入终端。这就是为什么你的grep命令似乎无法过滤掉错误消息;事实上,它甚至从未见过它们。

通过2>将标准错误流重定向到其他地方,这样其上生成的任何内容都不会最终出现在终端上。

重定向标准输出流的等效项是1>,它可以缩短为>

/dev/null文件很特殊。写入其中的所有内容都会完全消失。

在命令之后使用2>/dev/null意味着所有错误消息都被重定向到/dev/null而不是终端,因此被丢弃。

相关内容