Awk 显示模式匹配之前的n行和之后的m行是n&;m本身就是模式匹配
我有这样的数据:Awk 显示模式匹配之前的n行和之后的m行是n&;m本身就是模式匹配,awk,sed,grep,Awk,Sed,Grep,我有这样的数据: foo ... bar ... pattern ... ] 我需要首先匹配“模式”,然后显示“模式”之前到“foo”的所有内容,以及模式之后到“]”的所有内容 grep应该这样做: grep pattern -A grep foo -B grep ] 但遗憾的是,事实并非如此 答案不需要包括grep。 欢迎awk、sed和其他人。所以…您想在匹配foo的内容和匹配]的内容之间打印一个部分,如果它包含匹配模式的内容,是否正确?然后 sed -n '/foo/ { :a; N;
foo
...
bar
...
pattern
...
]
我需要首先匹配“模式”,然后显示“模式”之前到“foo”的所有内容,以及模式之后到“]”的所有内容
grep应该这样做:
grep pattern -A grep foo -B grep ]
但遗憾的是,事实并非如此
答案不需要包括grep。
欢迎awk、sed和其他人。所以…您想在匹配
foo
的内容和匹配]
的内容之间打印一个部分,如果它包含匹配模式的内容,是否正确?然后
sed -n '/foo/ { :a; N; /\]/!ba /pattern/ p }' filename
sed代码的工作原理如下:
/foo/ { # if a line matches foo
:a # jump label
N # fetch the next line and append it to the pattern space
/\]/! ba # if the result does not match ] (that is, if the last fetched
# line does not contain something that matches ]), go back to :a
/pattern/ p # if in all these lines, there is something that matches the
# pattern, print them
}
使匹配在前面不贪婪——也就是说,如果在文件中
1
foo
2
foo
3
pattern
4
]
5
匹配应包括3
和4
,但不包括2
,脚本可以这样修改(或类似修改,取决于您想要使用的模式):
其中,/\n[^\n]*foo/s/*\n/
将删除最后一个提取行之前的所有内容,如果该行中的内容与foo
匹配
如果您的模式是线型模式(即,如果它们包含^
或$
),则需要对其进行修改。一旦图案空间中有多行,^
将匹配图案空间的开头,$
将匹配图案空间的结尾,而不是一行。然后可以使用\n
匹配行尾。例如,如果您想在完全为foo
的行和完全为模式的行之间进行非贪婪匹配,则可以使用
sed -n '/^foo$/ { :a; N; /\nfoo$/ s/.*\n//; /\n\]$/!ba /\npattern\n/ p }' filename
这是一个awk
awk '/foo/ {t=1} t {a[++b]=$0} /pattern/ {f=1} /^]/ {if (f) for (i=1;i<=b;i++) print a[i];delete a;b=t=f=0}' file
awk '/foo/ {t=1} t {a[++b]=$0} /pattern/ {f=1} /^]/ {if (f) for (i=1;i<=b;i++) print a[i];delete a;b=t=f=0}'
foo
...
bar
...
pattern
...
]
使用awk测试
awk '/foo/ {t=1} t {a[++b]=$0} /pattern/ {f=1} /^]/ {if (f) for (i=1;i<=b;i++) print a[i];delete a;b=t=f=0}' file
awk '/foo/ {t=1} t {a[++b]=$0} /pattern/ {f=1} /^]/ {if (f) for (i=1;i<=b;i++) print a[i];delete a;b=t=f=0}'
foo
...
bar
...
pattern
...
]
awk'/foo/{t=1}t{a[++b]=$0}/pattern/{f=1}/^]/{if(f)for(i=1;i使用perl的单行代码:
perl -wln -0777 -e 'm/foo((?!foo).)*pattern[^\]]*\]/s and print $&;' [filename]
输入:
foo
foo
...
bar
...
pern
...
]
]
foo
...
pattern
]
]
foo
]
输出:
perl -wln -0777 -e 'm/foo((?!foo).)*pattern[^\]]*\]/s and print $&;' testtest
foo
...
pattern
]
一些要点:
在perl中使用m/../s
打开单行模式请参阅:
正则表达式foo((?!foo)。)*模式[^\]*\]
foo
匹配第一个foo
((?!foo)。*)*
避免在匹配零件中使用
模式
匹配模式
[^\]*\]
以下部分不应包含]
并以]
那么,您想要的确切输出是什么?您的示例输入不充分。显示示例输入,其中包括范围重叠和/或文件开始/结束出现在预期范围之前/之后的情况,等等,以及相关的输出。还要定义“模式”(ais是stginr、BRE、ERE还是其他什么?),并显示您是否想要完整的输入“word”或整行仅用于匹配或部分匹配。否则,我们只是猜测您几乎所有的需求。
perl -wln -0777 -e 'm/foo((?!foo).)*pattern[^\]]*\]/s and print $&;' testtest
foo
...
pattern
]