【问题标题】:Multiline replace with sed - Linux/Ubuntu用 sed 替换多行 - Linux/Ubuntu
【发布时间】:2016-04-07 09:38:58
【问题描述】:

原始文件如下所示:

BLABLA ABCABC blabl=
a blabla blabla ABC=
ABC blabla blabla A=
BCABC blabla

结果应该是这样的:

BLABLA DEFDEF blabl=
a blabla blabla DEF=
DEF blabla blabla D=
EFDEF blabla

所以所有ABCABC 都应该替换为DEFDEF,即使单词中有换行符(标有=)。

sed 可以吗?

【问题讨论】:

标签: linux bash sed


【解决方案1】:

Sed 多行,用于在任意位置连字符 ABCABC

$ sed -r 'N;s/A(=\n)?B(=\n)?C(=\n)?A(=\n)?B(=\n)?C/D\1E\2F\3D\4E\5F/g;P;D' infile
BLABLD AEFDEF blabl=
a blabla blabla DEF=
DEF blabla blabla D=
EFDEF blabla

N;P;D 是在模式空间中一次保留两行的惯用方式。替换检查 ABCABC 可选地穿插= 和任何位置的换行符,并且替换插入回捕获的内容。

这需要为? 运算符扩展正则表达式(BSD sed 中的-E)。 GNU sed 支持 BRE 中的 \? 作为扩展,但是所有的 () 也必须被转义。


如果= 只是象征换行符而实际上并不存在,这简化为

$ sed -r 'N;s/A(\n?)B(\n?)C(\n?)A(\n?)B(\n?)C/D\1E\2F\3D\4E\5F/g;P;D' infile
BLABLA DEFDEF blabl
a blabla blabla DEF
DEF blabla blabla D
EFDEF blabla

【讨论】:

    【解决方案2】:

    嗯,它不是多行,而是解决了你的例子:

    sed -r -e 's/ABC/DEF/g' -e 's/AB=/DE=/g' -e 's/A=/D=/g' -e 's/^BC/EF/g' -e 's/^C/F/g' infile
    

    【讨论】:

      【解决方案3】:

      试试这个,

      sed -i -e "s/ABC/DEF/g;s/A/D/g;s/B/E/g;s/C/F/g" filename.txt
      

      【讨论】:

        【解决方案4】:

        将 gnu awk 与 null RS 一起使用,您可以在单个替换中执行此操作(使用 gensub):

        awk -v RS= '{
           print gensub(/A(=\n)?B(=\n)?C(=\n)?A(=\n)?B(=\n)?C/, "D\\1E\\2F\\3D\\4E\\5F", "g", $0)
        }' file
        

        输出:

        BLABLA DEFDEF blabl=
        a blabla blabla DEF=
        DEF blabla blabla D=
        EFDEF blabla
        

        【讨论】:

          猜你喜欢
          • 2011-08-15
          • 1970-01-01
          • 2010-11-16
          • 1970-01-01
          • 2022-01-19
          • 2020-02-27
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多