【问题标题】:SAG challenge (sed, awk, grep): multi patterns file filteringSAG 挑战(sed、awk、grep):多模式文件过滤
【发布时间】:2010-10-11 06:47:21
【问题描述】:

所以我亲爱的 SOers,让我直截了当地说: 规范:使用成对的模式过滤文本文件。 示例:如果我们有一个文件:

line 1 blabla
line 2 more blabla
line 3 **PAT1a** blabla
line 4 blabla
line 5 **PAT1b** blabla
line 6 blabla
line 7 **PAT2a** blabla
line 8 blabla
line 9 **PAT2b** blabla
line 10 **PAT3a** blabla
line 11 blabla
line 12 **PAT3b** blabla
more and more blabla

应该给:

line 3 **PAT1a** blabla
line 4 blabla
line 5 **PAT1b** blabla
line 7 **PAT2a** blabla
line 8 blabla
line 9 **PAT2b** blabla
line 10 **PAT3a** blabla
line 11 blabla
line 12 **PAT3b** blabla

我知道如何使用“sed”只归档其中的一部分: sed -n -e '/PAT1a/,/PAT1b/{p}' 但是如何过滤所有的 sn-ps,我是否需要将这些模式对写入配置文件中,从中读取一对,使用上面的 sed cmd,转到下一对...?

注意:假设 PAT1、PAT2 和 PAT3 等没有公共前缀(如本例中的“PAT”)

还有一件事:如何在这篇文章的配额文本中换行而不留下一个完整的空白行?

【问题讨论】:

  • 这是一个实际问题还是“竞争”?如果是后者,将其标记为“社区维基”似乎更合适。至于你的最后一个问题:我通常把文字放在<pre></pre> 块中。
  • 要让引用的文本包含换行符,请使用代码格式化按钮,或者如果您使用>,则每行以两个空格结尾。

标签: sed awk grep


【解决方案1】:

我假设模式对是作为单独的文件给出的。然后,当它们按顺序出现在输入中时,您可以使用此awk 脚本:

awk 'NR == FNR { a[NR] = $1; b[NR] = $2; next }
     !s && $0 ~ a[i+1] { s = 1 }
     s
     s && $0 ~ b[i+1] { s = 0; i++ }' patterns.txt input.txt

当模式出现乱序时,还有一个更复杂的版本:

awk 'NR == FNR { a[++n] = $1; b[n] = $2; next }
     { for (i = 1; !s && i <= n; i++) if ($0 ~ a[i]) s = i; }
     s
     s && $0 ~ b[s] { s = 0 }' patterns.txt input.txt

【讨论】:

    【解决方案2】:

    哇。

    $ awk '/[0-9]a/{o=$0;getline;$0=o"\n"$0;print;next}/[0-9]b/' file
    line 3 PAT1a blabla
    line 4 blabla
    line 5 PAT1b blabla
    line 7 PAT2a blabla
    line 8 blabla
    line 9 PAT2b blabla
    line 10 PAT3a blabla
    line 11 blabla
    line 12 PAT3b blabla
    

    注意:既然你说“不共享公共前缀”,那么我使用数字和[ab] 模式作为正则表达式

    【讨论】:

      【解决方案3】:

      使用 b 命令跳过模式之间的所有行,使用 d 命令删除所有其他行:

      sed -e '/PAT1a/,/PAT1b/b' -e '/PAT2a/,/PAT2b/b' -e '/PAT3a/,/PAT3b/b' -e d
      

      【讨论】:

      • 我假设不可能使用单个正则表达式指定所有 a 模式和使用单个正则表达式指定所有 b 模式,否则 sed -n -e '/a-regex/,/b -regex/{p} 会起作用的。
      猜你喜欢
      • 1970-01-01
      • 2013-12-11
      • 1970-01-01
      • 1970-01-01
      • 2017-07-23
      • 1970-01-01
      • 2012-07-11
      • 2014-02-02
      • 1970-01-01
      相关资源
      最近更新 更多