使用grep命令的上下文行时,如何去除"--"行分隔符?

85

我有一个名为 compare.txt 的文本文件,我想提取每行中包含模式 nmse_gain_constant 的下一行。以下命令可以接近达成目标:

grep -A 1 nmse_gain_constant compare.txt | grep -v nmse_gain_constant

但是这个包含一个分隔符--,而且每行所需文字之间都有一条线。有什么简单的方法可以摆脱--行吗?

例如:对于一个看起来像下面这样的输入文件

line
line
nmse_gain_constant matching line
line after first match
line
line
nmse_gain_constant another matching line
line after second match
line
nmse_gain_constant a third matching line
line after third match

输出结果为

line after first match
--
line after second match
--
line after third match

但我只想要

line after first match
line after second match
line after third match
5个回答

117

我这样做:

 grep ... | grep -v -- "^--$"

但这样也可以(在许多操作系统上,但不是全部)!

grep --no-group-separator ...

并且它不会输出那个"--",甚至不会输出一个空行。


21
在Mac OS X上运行grep命令时出现错误:grep: unrecognized option '--no-group-separator' - krookedking
不要添加额外的grep,只需删除A标志即可。 - Eddie
--no-group-separator is not supported by all versions of grep - Eric
2
在Mac OS X上,您可以使用brew安装各种命令行工具的Gnu版本,包括grep。我相信默认情况下它被安装为ggrep(Gnu Grep)。这支持--no-group-separator选项。我已经这样做了,它有效。请参考此链接如何在macOS中安装和使用GNU Grep - steveb

25

grep存在一个未记录在文档中的参数: "--group-separator",它可以覆盖默认值"--"。你可以将其设置为""以去除双破折号。不过,你仍会得到一个空行。我曾遇到同样的问题,通过阅读grep源代码找到了这个参数。


11
您可以使用--no-group-separator(见下文) - Erik Aronesty
即使我设置了 --group-separator="",分组分隔符实际上仍然不为空,而是仍然被着色。因此,分隔线包含颜色代码,即 [[36m[[K[[m[[K,而不是空行。是否有办法在保持 grep --color=always 的情况下禁用分隔符的着色? - Martin Vegter
3
在 Mac 上的“BSD grep 2.5.1-FreeBSD”中不存在这样的选项。 - Timofey
1
我可以确认Tim的说法 - 我有相同版本的grep,但它不可用。 - Peter Clark
为什么不直接去掉添加此标志(A)的操作,而不是进行额外的处理呢? - Eddie
1
@eddie,搜索需要使用A标志才能找到用户想要的内容。很多时候,你都在寻找“某个东西之后的那一行”。 - Erik Aronesty

20

默认情况下,A开关会添加那些字符,因此这并不神秘。

man grep说明:

-A NUM

    Places  a  line  containing  a  group  separator  (--)   between
    contiguous  groups  of  matches.  With the -o or --only-matching
    option, this has no effect and a warning is given.

但是,您可以使用简单的sed来清理结果:

yourgrep | sed '/^--$/d'

1
使用 sed 的正则表达式对于这个任务来说有些过度了。为什么不使用 grep -v -- -- 呢? - Eric
-A 不仅添加“--”,还会在匹配后打印 NUM 行额外的内容。同样,-B 打印匹配前的 NUM 行,-C 打印匹配周围的 NUM 行上下文。"--" 用于分隔组。 - creynia
本回答假定使用 GNU 版本的 grep。比如说,那段 man 手册摘录并不符合至少 BSD grep,GNU 兼容的 2.6.0-FreeBSD 版本。而且,在此版本中,-A 标志并不是单独负责包含 -- 分隔符的。 - Jason Hemann

8

如果使用AWK,就无需使用太多的grep或其他工具(例如sed)进行管道操作:

awk '/nmse_gain_constant/{getline;print }' compare.txt

2
对于grep -B使用: awk '/regex/{ print x; print }; { x=$0 }' - D W
解释 awk 命令中的 getline 和 print 部分可能更适合这个答案,因为大多数试图使用 grep 而不是 awk 的人不熟悉用于获取 grep 等效结果的 awk 表达式。 - Steen

6
一种解决方案是:
grep -A 1 nmse_gain_constant compare.txt | grep -v nmse_gain_constant  | grep -v "\-\-"

2
不必要的引用和转义:使用 ...| grep -v -- -- 更简单。 - Eric

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接