【问题标题】:Replacing multiple lines using sed使用 sed 替换多行
【发布时间】:2022-01-19 18:13:50
【问题描述】:

美好的一天!

我试图弄清楚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' '\0' | sed -e 's#aa#NEW STRING#;s#bb#NEW STRING#' | tr '\0' '\n'
NEW STRING
NEW STRING
cc
dd

但是不使用tr怎么解决这个问题呢?

您能否提出一个我们不知道行号的案例?我们只知道aabb 之后。

【问题讨论】:

    标签: bash sed


    【解决方案1】:

    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
    

    例如,一行是aaa,另一行是bbb。我们知道 aaa 在 bbb 之前,但我们不知道他们在文件中的编号。

    我总结的一种方法(可能会有更好的方法;并且仅使用 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 将下一行追加到当前模式空间。如果它现在是 aa\nbb,则用两行 NEW STRING 行替换它,打印出模式空间,将其删除并重新开始。如果模式空间有其他内容,则打印出第一个换行符之前的所有内容,从模式空间中删除该文本,然后从 N 读取的第二行重新开始。

    【讨论】:

    • 如果我们不知道行号,但我们知道需要用正则表达式替换行怎么办?例如,一行是aaa,另一行是bbb。我们知道aaabbb 之前,但我们不知道文件中它们的编号。 bbb 位于 aaa 之后。谢谢!
    • @alex2020:如果您自己指定这些要求会更好。
    • @alex2020 查看编辑。
    • 最后的解决方案可能是sed '/^aa/{N;/^bb/M!{P;D};s/.*/new string/p}' file?
    【解决方案2】:

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

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

    输出:

    新字符串 新字符串 抄送 dd

    将第一行替换为 NEW STRING,然后复制模式空间以保留空间 (h)。在第二行将保持空间复制到模式空间 (g)。

    【讨论】:

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