grep:显示每个匹配项周围的行

4136

如何使用grep命令并显示每个匹配行前后的5行内容?


4
我为此目的保留了 Brendan Gregg 的 Perl 脚本 的副本。效果很好。 - Ethan Post
7
如果你需要在Solaris上运行的解决方案,请查看这个链接:http://www.unix.com/solaris/33533-grep-display-few-lines-before-after.html。 - jahroy
154
使用命令 man grep | grep -C 1 context 来查找与 "context" 相关的文本内容,其中 grep 命令可用于在文本中搜索匹配的字符串,而 man 命令用于显示 Linux 系统中的手册页面。 - StvnW
24
这段命令的意思是:在终端中输入 "man grep" 命令查看 grep 的使用手册,然后使用 grep 命令查找包含 "-C" 参数的行,并显示这一行及其上下各一行的内容。 - Anders B
16
@StvnW... 我不知道该怎么称呼那个概念(更一般的,而非 SO 的语境下的“meta”),或者该如何命名它。你通过展示如何使用答案来找到答案来回答了这个问题。 - bballdave025
也许在StackExchange的其他地方有人可以给我们答案。 - bballdave025
14个回答

5424

如果您使用的是BSDGNU grep,则可以使用-B num来设置匹配前几行的数量,-A num用于设置匹配后几行的数量。

grep -B 3 -A 2 foo README.txt

如果您希望在输出结果中保留相同数量的行数,您可以使用 -C num 命令。

grep -C 3 foo README.txt

这将显示前3行和后3行。


60
很遗憾,Solaris的grep不支持这个功能。请查看以下Solaris链接:http://www.unix.com/solaris/33533-grep-display-few-lines-before-after.html - рüффп
9
好的,但是如果我想显示匹配后的所有行怎么办?grep -A0和grep -A-1并不能完全胜任... - user67416
2
如果您使用的是HP-UX环境,则grep版本都无法像在Solaris中那样工作。我能够使用Solaris链接,但需要将其中的nawk替换为awk。 - zkarthik
6
-n选项是用来显示行号的,但对于某些版本的grep命令,-n#会显示带有行号的#周围的行(像-c一样)。这是一个很有用的快捷方式,当我需要上下文时经常使用。 - Anthony DiSanti
2
@g33kz0r,如果是这样的话,你应该单独提出一个问题来询问。(尽管有人在这里回答了你,但我不知道为什么...) - alexis
显示剩余11条评论

660

-A-B 都可以使用,-C n(用于显示上下文的 n 行),或者只需使用 -n(用于显示上下文的 n 行,只要 n 是1到9之间的数字)。


3
我尝试了“-n”格式,并发现它只能工作到“9”。对于“15”,它返回5行。 - Deepak Mahakale
20
这可能与 POSIX 程序通常如何解析命令行参数/选项有关。选项标识符是单个字符(例如“-A”,“-B”或“-C”)。通常,选项标识符后面跟着一个值(例如在 GCC 中指定输出文件的“-o a.out”),但它也可以作为一个简单的开关/标志(在 GCC 中启用调试信息的“-g”)。然而,选项之间的空格是可选的,因此对于没有值的选项,可以将它们合并在一起(例如“-ABC”),这意味着“-15”被解释为“-1 -5”(两个单独的选项),而“-5”覆盖了“-1”。 - natiiix
2
-5 比 -A 5 和 -B 5 都要快。它们不应该一起使用。如果您选择 -A 或 -B 或 -C 而不是 -9,对于脚本的其他读者来说更加清晰。 - Eric Aldinger
1
“-n”选项目前在(GNU grep) 3.1版本中适用于超过9行。 - mchid

82

ack使用与grep相似的参数,并接受-C,但通常更适用于搜索代码。


6
ACK 还支持 -A 和 -B 参数。 - Shuo
1
grep有一个优点,就是默认安装在许多系统上。 - Marc Z
3
@MarcZ:确实,grep更可能默认安装,而ack是一个便携、独立的脚本。无需编译或安装到诸如/usr/bin/之类的系统目录中。一旦下载并放置在$PATH列出的目录中(并设置其执行权限位),它应该能够立即使用。(不需要sudo或root权限来使ack运行。) - J-L
1
这个问题是关于 grep 的,不确定用它来“宣传” ack(确实是一个很棒的工具)是否是一个好主意... - MonsieurDart
2
为什么用它来搜索代码更好?您能在回答中详细说明一下吗?(但是不要包括“编辑:”,“更新:”或类似的内容 - 回答应该看起来像今天编写的。) - Peter Mortensen
显示剩余3条评论

42
grep astring myfile -A 5 -B 5

那将对 "myfile" 中的 "astring" 进行 grep 操作,并显示每个匹配项前后的 5 行。

25
"grep astring myfile -C 5" 将执行相同的操作。 - Syed Siraj Uddin
4
A: 哇,太棒了! B: Wow that's great! C: 无上下文信息。 - John Stoneman

23

ripgrep

如果你关心性能,建议使用 ripgrep,它具有类似于grep的语法,例如:

rg -C5 "pattern" .

-C--context NUM - 显示每个匹配之前和之后的NUM行。

还有一些参数,如-A/--after-context-B/--before-context

该工具构建在Rust的正则表达式引擎上,使其在处理大数据时非常高效


22

我通常使用

grep searchstring file -C n # n for number of lines of context up and down

许多工具,如grep,也有非常棒的man文件。我经常参考grep的man页面,因为你可以用它做很多事情。

man grep

许多GNU工具还有一个信息页面,除了手册页可能还包含更多有用的信息。

info grep

21

让我们通过一个例子来理解。
我们可以使用带有选项的grep:

-A 5  # this will give you 5 lines after searched string.
-B 5  # this will give you 5 lines before searched string.
-C 5  # this will give you 5 lines before & after searched string

例子。 File.txt 包含 6 行,以下是操作。

[abc@xyz]~/% cat file.txt # print all file data
this is first line
this is 2nd line
this is 3rd line
this is 4th line
this is 5th line
this is 6th line

[abc@xyz]~% grep "3rd" file.txt # we are searching for keyword '3rd' in the file
this is 3rd line

[abc@xyz]~% grep -A 2 "3rd" file.txt # print 2 lines after finding the searched string
this is 3rd line
this is 4th line
this is 5th line

[abc@xyz]~% grep -B 2 "3rd" file.txt # Print 2 lines before the search string.
this is first line
this is 2nd line
this is 3rd line

[abc@xyz]~% grep -C 2 "3rd" file.txt # print 2 line before and 2 line after the searched string 
this is first line
this is 2nd line
this is 3rd line
this is 4th line
this is 5th line

记忆选项的技巧:

  1. -A  → A 意味着 "After(之后)"
  2. -B  → B 意味着 "Before(之前)"
  3. -C  → C 意味着 "在C之间"

19

使用grep

$ grep --help | grep -i context
Context control:
  -B, --before-context=NUM  print NUM lines of leading context
  -A, --after-context=NUM   print NUM lines of trailing context
  -C, --context=NUM         print NUM lines of output context
  -NUM                      same as --context=NUM

1
你没有看过被接受的答案吗?你只是在重复一个将近10年历史的问题上已经被说过的话... - Yokai
9
抱歉,妖怪。但我没有在任何地方阅读到关于使用grep的帮助部分来检索答案的信息。 - chtenb
1
@Yokai 除了Chiel ten Brinke所说的之外,被接受的答案没有提到长选项。 - user3738870

19

如果你经常搜索代码,AG 比 grep 更高效(即更快)。

使用 -C 选项可以显示上下文行。

例如:

ag -C 3 "foo" myFile

line 1
line 2
line 3
line that has "foo"
line 5
line 6
line 7

2
你尝试过哪个系统(包括发行版名称和版本)?它是默认安装的吗?如果不是,有哪些安装说明?在Ubuntu MATE 20.04(Focal Fossa)上它不是默认安装的。 - Peter Mortensen

15

在Solaris上,当grep不支持-[ACB]选项时,在/some/file.txt中搜索“17655”,显示前后10行内容(使用Awk),输出以行号加冒号为前缀。

awk '

/17655/ {
        for (i = (b + 1) % 10; i != b; i = (i + 1) % 10) {
                print before[i]
        }
        print (NR ":" ($0))
        a = 10
}

a-- > 0 {
        print (NR ":" ($0))
}

{
        before[b] = (NR ":" ($0))
        b = (b + 1) % 10
}' /some/file.txt;

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