我有一个包含以下内容的文件:
zdk
aaa
b12
cdn
dke
kdn
输入1:aaa
和cdn
输出1:
aaa
b12
cdn
输入 2:zdk
和dke
输出2:
zdk
aaa
b12
cdn
dke
我可以使用以下命令来实现:
grep -a aaa -A2 file # Output 1
grep -a aaa -A4 file # Output 2
但在文件中我不知道结束字符串模式的确切出现位置(位置)(文件有 20000 行)
我怎样才能实现这个目标?
答案1
grep
这里帮不了你。sed
使用范围表达式可以更好地完成这项工作:
$ sed -n '/aaa/,/cdn/p' file
aaa
b12
cdn
$ sed -n '/zdk/,/dke/p' file
zdk
aaa
b12
cdn
dke
sed -n
抑制自动打印,以便仅在明确要求时才打印行。当范围/aaa/,/cdn/
发生时,就会发生这种情况。
这些范围表达式也可在 中使用awk
,您可以这样说:
awk '/zdk/,/dke/' file
当然,所有这些条件都可以扩展到更严格的正则表达式,例如sed -n '/^aaa$/,/^cdn$/p' file
检查行是否完全包含在aaa
和 上cdn
,没有其他内容。
答案2
可以通过以下方式完成sed
sed -n '
/^aaa$/,/^cdn$/w output1
/^zdk$/,/^dke$/w output2
' file
答案3
这是grep
命令:
grep -o "aaa.*cdn" <(paste -sd_ file) | tr '_' '\n'
您可以在 中实现多行匹配grep
,但您需要使用 perl-regexp for grep
(-P
- 并非每个平台都支持,例如 OS X),因此作为解决方法,我们用_
字符替换新行,之后grep
,我们将更改它们后退。
或者你可以使用pcregrep
它支持多线模式(-M
)。
或者使用ex
:
ex +"/aaa/,/cdn/p" -scq! file