对于 GNU sed
v4.2.2-7,info sed
表示:
'/REGEXP/M'
'\%REGEXP%M'
The 'M' modifier to regular-expression matching is a GNU 'sed'
extension which directs GNU 'sed' to match the regular expression
in 'multi-line' mode. The modifier causes '^' and '$' to match
respectively (in addition to the normal behavior) the empty string
after a newline, and the empty string before a newline. There are
special character sequences ('\`' and '\'') which always match the
beginning or the end of the buffer. In addition, the period
character does not match a new-line character in multi-line mode.
没有给出例子。经过测试,这个/M
后缀实际上是什么并不明显做。它似乎表现得像不 /M
根本不。
那么 的简单重要用法是什么/M
?其中“最简单”意味着“你好世界”简单,不需要太多其他程序的额外知识,“重要”意味着它应该用“/M”做一些值得注意的事情,如果缺少它就无法完成。
例如,以下实例:
seq 10 | sed -n '<code>;/<some regexp>/Mp'
...其行为不同于:
seq 10 | sed -n '<code>;/<some regexp>/p'
答案1
这相当于正则表达式运算符m
中的标志,或者在 perl 正则表达式或 PCRE 中使用,(尽管s标志也会删除perl 标志,因为没有, 's匹配换行符,而使用, 您需要标志 来匹配新队)。perl
(?m)
gsed
M
s
M
sed
.
perl
s
.
这些标志仅在模式空间包含多于一行时发挥作用,例如使用-z
, (读取 NUL 分隔记录)时,或者使用G
,N
或等命令向模式空间添加行时s
。
$ seq 3 | sed 'N;s/$/<foo>/g'
1
2<foo>
3
$ seq 3 | sed 'N;s/$/<foo>/Mg'
1<foo>
2<foo>
3
之后N
,模式空间包含1<newline>2
.如果没有M
,$
则仅匹配模式空间的末尾(之后2);与M
,$
匹配该模式空间中第一行末尾的两者(之后1,但在换行符之前),和在模式空间的末尾,(之后2)。
答案2
正如 Stéphane 指出的,当模式空间包含多于一行时,此修饰符非常有用。这里还有一些示例,使用'H;1h;$!d;x
它累积保留缓冲区中的所有行,然后在最后一行交换缓冲区,以便整个输入都在模式空间中。所以有了这个输入:
printf %s\\n 'onetwo' 'four' 'fivetwo' | sed 'H;1h;$!d;x;l;d'
这就是模式空间的样子:
onetwo\nfour\nfivetwo$
M
可能会派上用场
如果您需要匹配开头或/和结尾模式空间中的部分或全部线条:
printf %s\\n 'onetwo' 'four' 'fivetwo' | sed 'H;1h;$!d;x;s/^/DO/M2;s/$/END/Mg' onetwoEND DOfourEND fivetwoEND
如果您尝试查找不跨越多行的匹配项:
printf %s\\n 'onetwo' 'four' 'fivetwo' | sed 'H;1h;$!d;x;s/one.*two/MATCH/M' MATCH four fivetwo
如果您想在模式空间中的某些行以某种模式开始或结束的情况下操作模式空间(这是一个不与
s
:deletepatternspaceifoneendsof一起使用的示例ur
):printf %s\\n 'onetwo' 'four' 'fivetwo' | sed 'H;1h;$!d;x;/ur$/Md'
在所有这些示例中,如果删除,M
结果将会完全不同。然而,这并不意味着上面的操作没有 就不能完成M
,它只是更方便:
s/one.*two/MATCH/M'
与
s/one[^\n]*two/MATCH/'
或者
/ur$/Md'
与
/ur$\|ur\n/d'