【问题标题】:Print paragraphs that contain a set of patterns (order of occurrence doesn't matter)打印包含一组模式的段落(出现的顺序无关紧要)
【发布时间】:2020-12-23 06:21:23
【问题描述】:

给定一组模式A = {a_1, a_2, ..., a_n},我想打印包含所有这些模式的段落:a_1a_2、...、a_n

  • 段落以非空白字符开始,以仅包含空白字符的行结束。
  • 段落中模式出现的顺序无关紧要。

假设我有以下文件

$ cat main.txt
a

b

c

a
b

b
c

c
a

a
b
c

我想打印所有包含以下模式的段落:\<a\>\<b\>\<c\>。也就是说,输出应该是

$ {some command here}
a
b
c

我已经编写了以下命令。但是,这会将那些仅包含空格或制表符的行视为段落的一部分(请记住,仅包含空格的行不能被视为段落的一部分)。我认为这可以通过执行一次awk 来改善。

$ awk -v RS= '/\<a\>/ {print $0,"\n"}' main.txt |\
  awk -v RS= '/\<b\>/ {print $0,"\n"}' |\
  awk -v RS= '/\<c\>/ {print $0}'

a
b
c

有没有更有效的方法来做到这一点?

【问题讨论】:

  • 请将单词 pattern 替换为 stringregexp,无论您指的是哪个,在您的问题中出现的任何地方。 pattern 这个词是模棱两可的,所以在我们知道您的真正要求是什么(字符串或正则表达式匹配)之前,很容易提出错误的方法。还将a 等更改为更具代表性的字符串,包括正则表达式元字符、其他字符串的子字符串等,因此我们有一些有用的东西可供测试。

标签: shell awk text-processing


【解决方案1】:

你必须为空的RS准备你的输入:

awk '!NF{$0=""}1' main.txt > input.txt

这样,没有空白(非空)行将被视为段落的一部分,并且您消除了这些空白成为您的模式之一的可能性。实际上很难成为模式的一部分(但并非不可能),但是非常有可能统一段落,所以这个输入"a\n \nb\n\c" 会被认为是匹配所有模式的一个段落。


当然,您必须运行一次awk 才能同时测试每个段落的所有模式。但即使像你现在这样一次一次,只要你准备好输入,它就可以工作。

awk -v RS= '/\<a\>/ && /\<b\>/ && /\<c\>/{print $0,"\n"}' input.txt

【讨论】:

    猜你喜欢
    • 2017-05-03
    • 1970-01-01
    • 2020-09-10
    • 1970-01-01
    • 2018-05-19
    • 1970-01-01
    • 1970-01-01
    • 2011-12-11
    • 1970-01-01
    相关资源
    最近更新 更多