使用 sed 替换多行

Replacing multiple lines using sed

美好的一天!

我想弄清楚 hold spacepattern spacesed 中是如何工作的,所以我可以用它来替换多个字符串。

例如,如果要将第一行和第二行替换为NEW STRING

echo -e "aa\nbb\ncc\ndd\n"
aa
bb
cc
dd

为了获得这样的 STDOUT:

NEW STRING
NEW STRING
cc
dd

我正在尝试做类似的事情:

echo -e "aa\nbb\ncc\ndd\n" | sed -e 'commands'

我知道可以这样做:

echo -e "aa\nbb\ncc\ndd\n" | tr '\n' '[=13=]' | sed -e 's#aa#NEW STRING#;s#bb#NEW STRING#' | tr '[=13=]' '\n'
NEW STRING
NEW STRING
cc
dd

但是不使用tr如何解决这个问题呢?

您能否也建议我们不知道行号的情况?我们只知道aabb之后。

sed 命令接受一系列要操作的行:

$ printf "%s\n" aa bb cc dd | sed '1,2s/.*/NEW STRING/'
NEW STRING
NEW STRING
cc
dd

有些像 s 处理范围内的个别行,有些将整个范围视为一个块以将命令应用于:

$ printf "%s\n" aa bb cc dd | sed '1,2c\
NEW STRING'
NEW STRING
cc
dd

For example, one line is aaa, another line is bbb. We know that aaa comes before bbb, but we don't know their numbers in the file.

我拼凑的一种方法(可能会有更好的;并且只用 GNU sed 测试过)

$ printf "%s\n" qq rr aa bb cc aa xx dd |
  sed '/^aa$/{N; /^aa\nbb$/{s/.*/NEW STRING\nNEW STRING/; p; d}; P; D}'
qq
rr
NEW STRING
NEW STRING
cc
aa
xx
dd

如果当前行是 aaN 将下一行追加到当前模式 space。如果现在是 aa\nbb,用两行 NEW STRING 替换它,打印出模式 space,删除它并从新的一行开始。如果模式 space 有其他内容,打印出第一个换行符之前的所有内容,从模式 space 中删除该文本,然后仅从 N 读取的第二行重新开始在里面。

如果目标是试验模式 space 并保持 space,那么这就是一个例子:

echo -e "aa\nbb\ncc\ndd" | sed '1{ s/.*/NEW STRING/; h}; 2g'

输出:

NEW STRING
NEW STRING
cc
dd

将第一行替换为 NEW STRING,然后复制模式 space 以保留 space (h)。在第二行复制 hold space 到 pattern space (g).