使用 sed 命令替换多行

Replacing multiple line using sed command

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

file.log

ab
cd
ef

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

ab

ef

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

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

在 '\r' 之后有 3 个字符 space 但没有对此进行任何更改。

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

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

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

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

ef

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

所以当它读取第

行时
ab

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

cd

当它读取行 cd 时,它会从模式 space 中删除行 ab,这使得模式对于当前模式 space 无效.

解决方案

一个解决方案是读取整个文件,并将它们追加到保留 space 中,然后替换保留 space。作为

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

ef

它的作用

  • 1h 将第一行复制到保留 space.

  • 1!H 所有行除了第一行 (1!) 将行附加到保留 space.

  • $匹配最后一行,执行{..}

  • 中的命令
  • g 将 hold space 的内容复制回模式 space

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

  • p 打印整个模式 space.

其他几个选项:

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

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

如果只有一个就好了'ed

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

.
wq
END_SCRIPT