SAG挑战(sed,awk,grep):多模式文件过滤

时间:2010-10-11 06:47:21

标签: sed awk grep

亲爱的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}' 但是如何过滤所有片段,我是否需要在配置文件中编写这些模式对,从中读取一对,使用上面的sed cmd,转到下一对...?

注意:假设PAT1,PAT2和PAT3等没有共用前缀(在这种情况下就像'PAT')

还有一件事:如何在此帖子中为配额文字创建换行符而不留空白?

3 个答案:

答案 0 :(得分:2)

我假设模式对是作为单独的文件给出的。然后,当它们在输入中按顺序出现时,您可以使用此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

答案 1 :(得分:0)

awk中。

$ 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]模式进行正则表达式

答案 2 :(得分:0)

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

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