如果输出包含另一个表达式,则在 stdout 中打印与表达式匹配的行

如果输出包含另一个表达式,则在 stdout 中打印与表达式匹配的行

这可能是一个常见/简单的任务,但我无法从网络上的示例或 awk/sed/grep 手册中弄清楚。

所以,这是这样的场景:

  • 有一个内部命令行工具,可以为输入文件中的每一行打印出多行结果。
  • 我有一个 500K 行的输入文件。
  • 在该工具的输出中,总是有一行类似于“src:/some/directory”
  • 当且仅当同一输出中存在特定字符串“foo”时,我想提取这一行。

这些行之间的行数可能不同,所以这个问题有些相关,但不完全是我想要做的。 使用 awk 匹配单个文件中的多个正则表达式

如何使用 awk、sed 或 grep 执行此操作?我可以使用 Python 来完成此操作,但我不想这样做,因为我想学习 awk/sed,这可能是一个很好的例子。

这是我用 grep 尝试过的:

tool -inputfile | if grep "foo"; then grep "src: " ; fi > result.txt

这不会产生我预期的结果,可能是因为与缓冲相关的原因。

尝试使用 awk:

tool -inputfile | awk '{for (i=1;i<NF;i++) {if(match($i, "foo")) print ??? }}' > result.txt

如何打印此脚本中包含“src:”的行?

该工具的输出示例:

输出1:

src: /usr/bin 
param1: value1 value2 
param2: "foo" 
param3: "bar" "spam" 
param4: "eggs" "spam" "spam"

输出2:

src: /dev/null
param1: value1 value2
param2: "ham" "spam" "eggs"

因此,对于这两种情况,我尝试仅提取第一种情况,即: src: /usr/bin

答案1

如果您知道它src:出现在行的开头,并且foo用引号括起来,前面有一个空格,并且该行前面必须有一个冒号,请使用

awk 'BEGIN{a=0} /^$/{if(a==1) print b; a=0} /:.* "foo"/{a=1} /^src:/{b=$0} END{if(a==1) print b}'

我们使用变量a来记住模式是否foo出现在输入块中,并使用变量b来存储src:行。一开始,a被设置为 0。每当我们发现空行(即^$)时,我们就会检查 的值a,有条件地打印b并重置a。如果我们在行"foo"的前面遇到前面有一个冒号,我们设置a为 1。如果我们在行src:的开头遇到 ( ^),我们将其存储在 中b。最后,我们再次检查是否a == 1,如果是,则打印b

答案2

简单的 awk

awk '/src/{a=$0}/foo/{b=1}b&&a{print a;exit}'

如果srcfoo可以在其他地方以不同的格式或其他方式

awk '/^src/{a=$0}/"foo"/{b=1}b&&a{print a;exit}'

如果 foo 总是在后面src

awk '/^src/{a=$0}/"foo"/{print a;exit}'

如果一个文件中有多个 src 块,并且您想要打印每个包含 foo 的块

awk '/^src/{a=$0;b=0}/"foo"/{b=1}b&&a{print a;a=0}'

相关内容