怎么告诉sed“dot match new line”

时间:2011-12-24 11:36:04

标签: sed

我无法想象如何告诉sed dot match new line

echo -e "one\ntwo\nthree" | sed 's/one.*two/one/m'

我希望得到:

  

一个
  三个

相反,我得到原创:

  

一个
  2个
  三个

6 个答案:

答案 0 :(得分:4)

sed是基于行的工具。我不认为这是一种选择 您可以使用h/H(暂停),g/G(获取)。

$ echo -e 'one\ntwo\nthree' | sed -n '1h;1!H;${g;s/one.*two/one/p}'
one
three

也许你应该尝试vim

:%s/one\_.*two/one/g

答案 1 :(得分:3)

你可以这样使用python:

$ echo -e "one\ntwo\nthree" | python -c 'import re, sys; s=sys.stdin.read(); s=re.sub("(?s)one.*two", "one", s); print s,'
one
three
$

这将读取整个python的标准输入(sys.stdin.read()),然后将“one”替换为“one。* two”和dot matches all setting enabled(在正则表达式的开头使用(?s) )然后打印修改后的字符串(打印中的尾随逗号用于防止打印添加额外的换行符。)

答案 2 :(得分:1)

这可能对您有用:

<<<$'one\ntwo\nthree' sed '/two/d'

<<<$'one\ntwo\nthree' sed '2d'

<<<$'one\ntwo\nthree' sed 'n;d'

<<<$'one\ntwo\nthree' sed 'N;N;s/two.//'

Sed 确实使用点\n匹配所有字符(包括.),但通常它已经删除了\n,作为循环的一部分,因此它不再出现在要匹配的模式空间中。

只有某些命令(NHG)会在模式/保留空间中保留换行符。

  1. N在图案空间中添加换行符,然后附加下一行。
  2. H完全相同,除非它作用于保留空间。
  3. G在模式空间中附加换行符,然后附加保留空间中的任何内容。
  4. 保留空格为空,直到您在其中放置内容为止:

    sed G file
    

    将在每行后插入一个空行。

    sed 'G;G' file
    

    将插入2个空行等等。

答案 3 :(得分:0)

两个sed电话怎么样:
(首先摆脱'两个',然后摆脱空白线)

$ echo -e 'one\ntwo\nthree' | sed 's/two//' | sed '/^$/d'
one
three

实际上,我更倾向于将Perl用于Python上的单行:

$ echo -e 'one\ntwo\nthree' | perl -pe 's/two\n//'
one
three

答案 4 :(得分:0)

下面的讨论基于Gnu sed。

sed逐行操作。因此,不可能告诉它点匹配换行符。但是,有一些技巧可以实现此目的。您可以使用循环结构(类似)将所有文本放入模式空间,然后执行操作。

要将所有内容放在模式空间中,请使用:

:a;N;$!ba;

要间接设置“点匹配换行符”,请使用:

(\n|.)

结果是:

root@u1804:~# echo -e "one\ntwo\nthree" | sed -r ':a;N;$!ba;s/one(\n|.)*two/one/'
one
three
root@u1804:~#

请注意,在这种情况下,(\n|.)匹配换行符和所有字符。参见以下示例:

root@u1804:~# echo -e "oneXXXXXX\nXXXXXXtwo\nthree" | sed -r ':a;N;$!ba;s/one(\n|.)*two/one/'
one
three
root@u1804:~#

答案 5 :(得分:0)

如果您使用GNU sed,则可以将任何字符(包括换行符)与仅.匹配,请参见

.
匹配任何字符,包括换行符。

您只需要使用-z option

echo -e "one\ntwo\nthree" | sed -z 's/one.*two/one/'
# => one
#    three

请参见online sed demo

但是one.*two可能不是您所需要的,因为*在POSIX正则表达式模式中总是很贪婪。因此,one.*two将匹配最左边的one,然后匹配尽可能多的0个或更多字符,然后匹配最右边的two。如果您需要删除one,则尽可能删除0个以上的字符,然后再删除最左边的two,则必须使用perl:< / p>

perl -i -0 -pe 's/one.*?two//sg' file             # Non-Unicode version
perl -i -CSD -Mutf8 -0 -pe 's/one.*?two//sg' file # S&R in a UTF8 file 

-0选项启用slurp mode,以便可以整体读取文件,而不是逐行读取,-i将启用内联文件修改,{{1} }将使s与任何字符匹配,包括换行符,并且由于.非贪婪,.*?将与任何0个或更多字符匹配,并尽可能少地匹配。 *?部分确保您的输入已解码,并且输出正确地重新编码。