希望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 和 d 之间的模式。从第一个 c 开始计数应该是保持 c 和 d 的数量,以便当计数匹配时,第一个 c 和匹配之间的部分 d 应输入一个文件,其中包含 d 匹配的行号。
在这个特定的例子中,匹配发生在第七只狗上,因此输出必须是:
cat cat cat cat cat cat dog rat ate dog tit
dog cat dog dog dog rat d
比赛可以超越两条线! 输出可以包含也可以不包含 c 和 d 。文本中存在包含特殊字符的各种字符! 为了进行打印,必须匹配计数。
提前感谢您的回复。建议随时欢迎。
编辑:只要满足条件并且出口的行号 d <,就可以破坏 c 和 d 之间的模式捕获/ strong>获得:)
答案 0 :(得分:4)
一些提示,但未提供完整的解决方案:
默认情况下,awk将每一行视为记录。默认记录分隔符为RS="\n"
。
根据您的awk版本,您可以将记录分隔符RS
设置为与c
或d
匹配的正则表达式。然后,对于每条记录,您可以查看RT
变量,该变量将包含c
或d
,具体取决于实际匹配的内容。从那里开始,使用在c
上递增的变量,在d
递减时,您将能够在匹配结束时找到匹配的结尾。
然后,您可以使用包含您的匹配项的变量,并将RT
和新记录连接到该变量,直到您完成为止。
如果您需要知道匹配结束的行号,可以将RS
设置为与之前匹配c
,d
的正则表达式,还可以添加匹配\n
的可能性。每当RT
告诉您\n
已匹配时,通过维持另一个计数器变量递增,您将获得您的行号。
答案 1 :(得分: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'
这会打印从最长到最短的所有令人满意的序列。