2

希望 AWK 大师可以为我的问题提供解决方案。

我有一个像这样的文件:

cat cat cat cat cat cat dog rat ate dog tit 
dog cat dog dog dog rat dog pat ate cat dog

我必须使用 AWK 来提取第一个出现的c和 a d之间的模式。从第一个c开始,计数应该保持在cd的数量上,这样当计数匹配时,第一个c和匹配的d应该被输出到一个文件中,其中包括匹配 d 的行

在此特定示例中,匹配发生在第七只狗上,因此输出必须是:

cat cat cat cat cat cat dog rat ate dog tit 
dog cat dog dog dog rat d

比赛可以超越两条线!输出可以或不能包括cd。文本中存在包括特殊字符在内的各种字符!为了进行打印,计数必须匹配。

提前感谢您的回复。建议总是受欢迎的。

编辑:只要满足条件并获得出口d的行号,就可以破坏cd之间模式的捕获:)

4

2 回答 2

4

一些提示,但没有给出完整的解决方案:

默认情况下,awk 将每一行视为一条记录。默认记录分隔符是RS="\n".

根据您的 awk 版本,您可以将RS记录分隔符设置为与c或匹配的正则表达式d。然后,对于每条记录,您可以检查RT变量,该变量将包含cd,具体取决于实际匹配的内容。从那里开始,使用递增 on c,递减 on的变量,d当它达到 0 时,您将能够找到匹配的结束。

然后,您可以使用包含到目前为止匹配项的变量,并继续RT将新记录连接到它,直到完成。

如果您需要知道匹配结束的行号,您可以设置为匹配,RS的正则表达式,如前所述,但也添加匹配的可能性。通过维护另一个计数器变量,每次递增告诉您已匹配,您将获得行号。cd\nRT\n

于 2012-06-22T13:39:43.140 回答
1

这是一个sed有趣的解决方案:

sed -rne ':r;$!{N;br};s/^[^c]*(.*d)[^d]*$/\1/;:a;h;s/[^cd]//g;' \
-e ':s;s/d(.*)c/c\1d/;ts;s/cd/c\nd/;T;y/c/d/;/^(d+)\n\1$/{g;i -------' \
-e 'p};g;s/d[^d]*d$/d/;ta'

这将打印从最长到最短的所有令人满意的序列。

于 2012-06-22T15:46:51.250 回答