如何 grep 文件中的文本并显示包含该文本的段落?

如何 grep 文件中的文本并显示包含该文本的段落?

以下是文件中的文本:

Pseudo name=Apple
Code=42B
state=fault

Pseudo name=Prance
Code=43B
state=good

我需要 grep 查找“42B”并从上面的文本中获取输出,例如:

Pseudo name=Apple
Code=42B
state=fault

有谁知道如何使用grep//来实现这awk一点sed

答案1

awk

awk -v RS='' '/42B/' file

RS=将输入记录分隔符从换行符更改为空行。如果记录中的任何字段包含/42B/打印该记录。

''(空字符串)是一个神奇的值,用于表示空行根据 POSIX:

如果RS为空,则记录由由 a 加一个或多个空行组成的序列分隔<newline>,前导或尾随空行不应导致输入的开头或结尾处出现空记录,并且 a<newline>应始终是字段分隔符,无论有什么价值FS是。

输出段落不会被分隔,因为输出分隔符仍然是单个换行符。为了确保输出段落之间有空行,请将输出记录分隔符设置为两个换行符:

awk -v RS='' -v ORS='\n\n' '/42B/' file

答案2

假设数据是结构化的,因此它始终是您想要的之前和之后的行,您可以使用 grep 的-A(之后)和-B(之前)开关来告诉它包含匹配之前的 1 行和匹配之后的 1 行:

$ grep -A 1 -B 1 "42B" sample.txt
Pseudo name=Apple
Code=42B
state=fault

如果您希望搜索词前后有相同的数字行,您可以使用-C(context) 开关:

$ grep -C 1 "42B" sample.txt
Pseudo name=Apple
Code=42B
state=fault

如果您想在匹配多行时更加严格,可以使用该工具pcregrep,匹配多行模式:

$ pcregrep -M 'Pseudo.*\n.*42B.*\nstate.*' sample.txt
Pseudo name=Apple
Code=42B
state=fault

上面的模式匹配如下:

  • -M- 多行
  • 'Pseudo.*\n.*42B.*\nstate.*'- 匹配一组字符串,其中第一个字符串以单词开头,"Pseudo"后跟任何字符,直到行尾\n,然后是任何字符,直到该字符串,"42B"后跟任何字符,直到行的另一端 ( \n),最后是字符串"state"后跟任何字符。

答案3

某些 Unix风格grep的 Unix 版本有-p“段落”标志。我知道AIX 确实如此

grep -p 42B <myfile>

会完全按照你的要求去做。 YMMV 和 GNU grep 没有这个标志。

答案4

另一个 perl 解决方案,没有尾随空行:

perl -00ne 'if ($_ =~ /42B/) {chomp($_); printf "%s\n",$_}' foo

例子

% perl -00ne 'if ($_ =~ /42B/) {chomp($_); printf "%s\n",$_}' foo
Pseudo name=Apple
Code=42B
state=fault

% cat foo
Pseudo name=Apple
Code=42B
state=fault

Pseudo name=Prance
Code=43B
state=good

相关内容