grep 的输出上下文(-C)会产生大量文件

grep 的输出上下文(-C)会产生大量文件

任务:

我用来grep搜索一些文本文件,将结果从一个grep(不包括某些行)传输到另一个(匹配某些行)+使用参数显示一些上下文,-C如下所示:

grep -v "Chapter" *.txt | grep -nE  -C1 " leaves? " 

问题:

这在打印结果时效果很好,但会产生非常大的文件(〜几GB),并且当我将其写入文件时需要很长时间,如下所示:

grep -v "Chapter" *.txt | grep -nE  -C1 " leaves? " > out.txt

故障排除:

  1. 仅返回grep1345 行(根据wc),打印输出需要几秒钟

  2. 大型输出文件中的输出看起来合法,也称为输入文件的实际结果。

  3. 将运算符替换-C-Aor-B会生成 KB 大小的良好输出文件。

问题:

  • 为什么会发生这种情况?
  • 有什么东西可以-C这样破坏事情吗?
  • 还是我忽略了其他问题?

任何提示表示赞赏!在 MacOS 终端中运行它。我正在关注男人。

答案1

尝试更改您正在写入的目录out.txt。例如将此命令更改为:

$ grep -v "Chapter" *.txt | grep -nE  -C1 " leaves? " > /tmp/out.txt

例子

在这里,您可以看到在 Bash shell 中启用详细输出时发生的情况。

$ set -x
$ grep -v "Chapter" *.txt | grep -nE  -C1 " leaves? " > out.txt
+ grep --color=auto -nE -C1 ' leaves? '
+ grep --color=auto -v Chapter file01.txt file02.txt file03.txt file04.txt file05.txt file06.txt file07.txt file08.txt file09.txt file10.txt out.txt

请注意,它接受参数*.txt并对其进行扩展,并且它包括 file out.txt。因此,您在写入时实际上是在解析该文件。

为什么?

如果您考虑一下当第一个命令的输出通过管道传输到下一个命令时 shell 会做什么,这是有道理的。 shell 解析您刚刚给它的命令,寻找管道 ( |)。当遇到它们时,它必须运行右侧的命令,以便在管道内发生的命令之间设置 STDIN/STDOUT 的重定向。

您可以使用该sleep命令来查看 shell 在添加更多管道时如何解析内容:

$ sleep 0.1 | sleep 0.2 | sleep 0.3 | sleep 0.4
+ sleep 0.2
+ sleep 0.3
+ sleep 0.4
+ sleep 0.1

$ sleep 0.1 | sleep 0.2 | sleep 0.3 | sleep 0.4 | sleep 0.5
+ sleep 0.2
+ sleep 0.3
+ sleep 0.4
+ sleep 0.5
+ sleep 0.1

echo通过+写入文件来执行此操作还可以通过文件访问和stat命令显示顺序:

$ echo "1" > file1 | echo "2" > file2 | echo "3" > file3 | echo "4" > file4
+ echo 2
+ echo 3
+ echo 4
+ echo 1

$ stat file* | grep -E "File|Access: [[:digit:]]+"
+ grep --color=auto -E 'File|Access: [[:digit:]]+'
+ stat file1 file2 file3 file4
  File: ‘file1’
Access: 2018-08-11 23:55:20.868220474 -0400
  File: ‘file2’
Access: 2018-08-11 23:55:20.865220576 -0400
  File: ‘file3’
Access: 2018-08-11 23:55:20.866220542 -0400
  File: ‘file4’
Access: 2018-08-11 23:55:20.867220508 -0400

相关内容