将 grep 输出限制为短行

将 grep 输出限制为短行

我经常使用 grep 来查找具有特定条目的文件,如下所示:

grep -R 'MyClassName'

好处是它会返回文件及其内容,并将找到的字符串标记为红色。坏处是,我还有一些大文件,其中的整个文本都写在一行中。现在 grep 在这些大文件中查找文本时输出太多。有没有办法将输出限制为例如左右各 5 个单词?或者将输出限制为左右各 30 个字母?

答案1

grep本身只有基于行的上下文选项。另一种选择是这篇 SU 帖子

一种解决方法是启用“仅匹配”选项,然后使用 RegExp 的功能来 grep 比文本更多的内容:

grep -o ".\{0,50\}WHAT_I_M_SEARCHING.\{0,50\}" ./filepath

当然,如果您使用颜色突出显示,您可以随时再次 grep 以仅为真正的匹配着色:

grep -o ".\{0,50\}WHAT_I_M_SEARCHING.\{0,50\}"  ./filepath | grep "WHAT_I_M_SEARCHING"

作为另一种选择,我建议fold文本,然后对其进行 grep,例如:

fold -sw 80 input.txt | grep ...

-s选项将把fold单词推到下一行,而不是在中间断行。

或者使用其他方法根据输入的结构将输入拆分成行。(例如,SU 帖子处理了 JSON,因此使用jq等进行漂亮打印和grep...或仅使用jq其本身进行过滤...会比上面给出的两种替代方案中的任何一种都好。)


这个 GNU awk 方法可能更快:

gawk -v n=50 -v RS='MyClassName' '
  FNR > 1 { printf "%s: %s\n",FILENAME, p prt substr($0, 0, n)}
  {p = substr($0, length - n); prt = RT}
' input.txt
  • 告诉 awk 根据我们感兴趣的模式 ( -v RS=...) 和上下文中的字符数 ( -v n=...)拆分记录
  • 第一条记录(FNR > 1)之后的每一条记录都是 awk 找到的与模式匹配的记录。
  • 因此,我们打印上n一行的尾随字符(p)和n当前行的前导字符(substr($0, 0, n)),以及上一行的匹配文本(即prt
    • 我们设定pprt 打印,所以我们设置的值被下一个线
    • RT是一种 GNUism,这就是为什么它是 GNU awk 特有的。

对于递归搜索,也许:

find . -type f -exec gawk -v n=50 -v RS='MyClassName' 'FNR>1{printf "%s: %s\n",FILENAME, p prt substr($0, 0, n)} {p = substr($0, length-n); prt = RT}' {} +

答案2

使用唯一匹配与其他一些选项结合(见下文),可能非常接近您所寻求的,而没有其他答案中提到的正则表达式的处理开销

grep -RnHo 'MyClassName'
  • n数字输出,显示匹配的行号
  • H文件名,在匹配行的开头显示文件名
  • o仅匹配,仅显示匹配的字符串,而不是整行

相关内容