我希望有一个替换或打印样式命令,正则表达式跨行。线条保留。
$ echo -e 'a\nb\nc\nd\ne\nf\ng' | tr -d '\n' | grep -or 'b.*f'
bcdef
或
$ echo -e 'a\nb\nc\nd\ne\nf\ng' | tr -d '\n' | sed -r 's|b(.*)f|y\1z|'
aycdezg
我想使用grep或sed,因为我想知道人们在awk或perl之前会做些什么..
他们没有吗?是。*不可用?他们没有其他同等的东西吗?可能使用横跨行的正则表达式修改某些输入,并将其打印到stdout或输出到文件,保留行。
答案 0 :(得分:1)
sed
可以通过使用N
命令跨换行符进行匹配。例如,以下sed
命令会将bar
替换为newline
,然后foo
替换为###
:
$ echo -e "foo\nbar\nbaz\nqux" | sed 'N;s/bar\nbaz/###/;P;D'
foo
###
qux
N
命令会将下一个输入行追加到当前模式空间,并由嵌入的换行符\n
)P
命令将打印当前模式空间,包括第一个嵌入的换行符。D
命令将删除模式空间中的第一个嵌入换行符。它也将在下一个周期开始,但如果模式空间中仍有数据,则跳过读取输入。通过使用这3个命令,您基本上可以在N行中进行任何类型的s
命令替换。
如果您的问题是我如何在上述两个示例中删除了对tr
的需求,只需使用sed
,那么请转到:
$ echo -e 'a\nb\nc\nd\ne\nf\ng' | sed ':a;N;$!ba;s/\n//g;y/ag/yz/'
ybcdefz
答案 1 :(得分:1)
这应该做你想要的:
$ echo -e 'a\nb\nc\nd\ne\nf\ng' | sed ':a;$s/b\([^f]*\)f/y\1z/;N;ba'
a
y
c
d
e
z
g
它累积所有行,然后进行替换。它寻找第一个“f”。如果您希望它查找最后一个“f”,请将[^f]
更改为.
。
请注意,在 sed
或AWK可用后,这可能会使用添加到Perl 的功能(AWK围绕 looong < / em>时间)。
修改强>
要进行多行grep
只需要稍加修改:
$ echo -e 'a\nb\nc\nd\ne\nf\ng' | sed ':a;$s/^[^b]*\(b[^f]*f\)[^f]*$/\1/;N;ba'
b
c
d
e
f
答案 2 :(得分:0)
经过验证的救援工具。
echo -e "foo\nbar\nbaz\nqux" | perl -lpe 'BEGIN{$/=""}s/foo\nbar/###/'