【问题标题】:grep command to add end line after every match [duplicate]grep命令在每场比赛后添加结束行[重复]
【发布时间】:2014-01-01 06:58:30
【问题描述】:

你知道如何添加一些结束行,比如

"=========================================================================================="

每场比赛后

tail -f error.log -n 2000 | grep -B 10 -A 25 'Exception:'

此命令打印所有异常日志,但我喜欢为每个异常日志看到一个分隔线。

【问题讨论】:

  • 在没有-o 的情况下指定-A-B 时,grep 是否已经在匹配项之间放置了-- 之类的分隔符?
  • @starrify 这是我的第一个想法,但 grep 命令产生 26 行(之前 10 行,之后 25 行) - 然后 OP 想要添加单行。我不确定如何识别那个“块”(也许是 awk,每 36 行添加分隔符)。
  • @Floris 感谢您指出这一点。我也有同样的想法,我编辑了我的评论......每 36 行添加一个分隔符是可以的,但仍然需要处理没有足够行的第一个和最后一个匹配项..
  • @starrify - 我很晚才意识到您更新的评论直接指向我发布的解决方案。向你大声喊叫!

标签: linux shell unix grep


【解决方案1】:

您发布了一个没有执行您想要的命令并描述了它的输出,但您没有告诉我们您想要什么,所以这是一个猜测,但也许它会有用。它打印一些正则表达式之前的 2 行和之后的 3 行:

$ cat file
a
b
c
d
FOO
e
f
g
h
i
j
FOO
k
l
m
n
o

$ awk -v re="FOO" -v b=2 -v a=3 'NR==FNR{line[FNR]=$0;next} $0 ~ re{for (i=(FNR-b);i<=(FNR+a);i++) print line[i]; print "=====" }' file file
c
d
FOO
e
f
g
=====
i
j
FOO
k
l
m
=====

【讨论】:

  • 有趣 - 我之前没有使用 -v 导入变量。使其成为一个非常灵活的解决方案。我喜欢!
  • 您应该始终默认使用 -v 来使用外部值来 int awk 变量。详情请见cfajohnson.com/shell/cus-faq-2.html#Q24
【解决方案2】:

我更喜欢 sed 进行文本操作:

# cat test 
1
Exception
2
Exception
3
4
Exception
5
Exception
6
7
8
Exception
9



# sed -i '/Exception/a =========================' test 


# cat test 
1
Exception
=========================
2
Exception
=========================
3
4
Exception
=========================
5
Exception
=========================
6
7
8
Exception
=========================
9

【讨论】:

  • AFAIK OP 正在寻找在 Exception 之前和之后选择一些行并在每个块的末尾打印 ==== 行,而不是在 Exception 之后简单地打印 ==== 行。跨度>
  • 我正在寻找一种方法来使用 sed grep 某些内容并将文本添加到所有匹配项中,这对此很有帮助。
  • 另一种方式:grep "match" | sed -n -e 's/match/match\/n=======/p'
【解决方案3】:

对于像我这样拥有不包含 --group-separator 选项的“非常老”的 grep 的人来说,以下似乎是可以接受的解决方法。

注意到grep(我的版本,2.5.1)确实会在组(--)之间产生一个“小的默认”分隔符,您可以轻松地将该字符串替换为您选择的字符串:

tail -f rms.log -n 2000 | grep -B 10 -A 25 'Exception:' | sed 's/^--$/=================/'

这确实将-- 替换为============

显然,您可以根据自己的喜好对其进行修改。如果您可以选择使用--group-separator(@sudo_O 的回答),那显然更可取。

EDIT 阅读问题下方的 cmets,我意识到当 @starrify 更新他的评论(我之前没有注意到)时,他的评论基本上直接指向了这个解决方案 - 所以我觉得我拥有他顶一下……

【讨论】:

  • 您使用的是哪个版本的grep?在什么平台上?你会得到什么输出/错误信息?
【解决方案4】:

您需要以下选项:

--group-separator=SEP
使用 SEP 作为组分隔符。默认情况下,SEP 是双连字符 (--)。

演示:

$ cat file
before
exception 1
after
foo
bar
before
exception 2
after

$ grep -A 1 -B 1 --group-separator======================== exception file 
before
exception 1
after
=======================
before
exception 2
after

【讨论】:

  • 我每天都在 SO 上学到新东西。很高兴早上第一件事就把它弄出来!这显然是正确的解决方案。
  • ...+1。然而,grep --helpman 1 grep 都没有提供这样的选项——虽然可以将它传递给 grep >
  • @starrify FWIW, grep 还可以选择消除分隔符--no-group-separator
  • @starrify 奇怪但真实——man grep 没有列出您已经提到的选项,但info grep 列出了!
  • 这是grep (GNU grep) 2.14 我不能确定其他变体支持此选项 MAC/BSD grep。该选项在我的系统上与--helpman grepinfo grep 一起列出,奇怪的是它受支持,但对你们中的某些人没有记录。
猜你喜欢
  • 2021-08-24
  • 2016-01-29
  • 2013-09-17
  • 2014-08-16
  • 2022-11-23
  • 2014-04-05
  • 1970-01-01
  • 1970-01-01
  • 2021-03-06
相关资源
最近更新 更多