【问题标题】:Replacing multiple line using sed command使用 sed 命令替换多行
【发布时间】:2015-01-14 15:28:31
【问题描述】:

我有一个文本文件 file.log 包含以下文本

文件.log

ab
cd
ef

我想用“ab\n”替换“ab\ncd”,最终的file.log应该是这样的:

ab

ef

这是我正在使用的 sed 命令,但它无法识别换行符以匹配模式:

sed -i 's/\(.*\)\r   \(.*\)/\1\r/g' file.log

在 '\r' 之后有 3 个字符空格,但不会对此进行任何更改。

\(.*\) - 匹配任何字符 (.) 后跟前一个字符的 0 个或多个 (*) \r - 换行 \1 - 替换第一个匹配模式。在这种情况下,它是'ab'

你能帮我看看上面的命令有什么问题吗?

【问题讨论】:

    标签: linux sed


    【解决方案1】:

    问题在于,sed 是一个流编辑器,它从输入文件中逐行读取

    所以当它读取行时

    ab
    

    从输入文件中,它不知道该行是否后跟一行

    cd
    

    当它读取cd 行时,sed 将从模式空间中删除ab 行,这使得模式对于当前模式空间无效。

    解决方案

    解决方案可以是读取整个文件,并将它们追加到保持空间中,然后替换保持空间。作为

    $ sed -n '1h; 1!H;${g;s/ab\ncd/ab\n/g;p}' input
    ab
    
    ef
    

    它的作用

    • 1h 将第一行复制到保留空间中。

    • 1!H 除第一行以外的所有行 (1!) 都将该行附加到保留空间。

    • $匹配最后一行,执行{..}中的命令

    • g 将保持空间的内容复制回模式空间

    • s/ab\ncd/ab\n/g 进行替换。

    • p 打印整个图案空间。

    【讨论】:

    • 非常感谢!这有帮助。
    【解决方案2】:

    Sed 逐行处理输入文件。所以不能像上面那样做。您需要包含N,以便它将下一行附加到模式空间中。

    $ sed 'N;s~ab\ncd~ab\n~g' file
    ab
    
    ef
    

    【讨论】:

      【解决方案3】:

      其他几个选项:

      perl -i -0pe 's/^ab\n\Kcd$//mg' file.log
      

      这将改变文件中的任何此类模式

      如果只有一个,那就好'ed

      ed file.log <<END_SCRIPT
      /^ab$/+1 c
      
      .
      wq
      END_SCRIPT
      

      【讨论】:

        猜你喜欢
        • 2018-09-16
        • 2022-01-10
        • 2013-11-04
        • 1970-01-01
        • 2020-10-09
        • 2013-10-11
        • 2020-09-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多