如何使用sed

时间:2017-11-02 21:13:02

标签: macos shell sed

在shell脚本中,如何在某个模式后添加行?假设我有以下文件,我想在block 1blk 2之后添加两行。

abc
def

[block 1]
    apples = 3
    grapes = 4

[blk 2]
    banana = 2
    apples = 3

[block 1][blk 2]将出现在文件中。

我期待的输出低于。

abc
def

[block 1]
    oranges = 5
    pears = 2
    apples = 3
    grapes = 4

[blk 2]
    oranges = 5
    pears = 2
    banana = 2
    apples = 3

我想过用sed做这件事。我尝试了下面的命令,但它在我的Mac上不起作用。我查看了these posts,但我无法找到我做错的事。

$sed -i '/\[block 1\]/a\n\toranges = 3\n\tpears = 2' sample2.txt
sed: 1: "sample2.txt": unterminated substitute pattern

我该如何解决这个问题?谢谢你的帮助!

[编辑] 我尝试了下面的内容,这些在我的Mac上无法正常工作。

$sed -E '/\[block 1\]|\[blk 2\]/r\\n\\toranges = 3\\n\\tpears = 2' sample2.txt
abc
def

    [block 1]
        apples = 3
        grapes = 4

    [blk 2]
        banana = 2
        apples = 3

$sed -E '/\[block 1\]|\[blk 2\]/r\n\toranges = 3\n\tpears = 2' sample2.txt
abc
def

    [block 1]
        apples = 3
        grapes = 4

    [blk 2]
        banana = 2
        apples = 3

Awk尝试:

$awk -v RS= '/\[block 1\]/{$0 = $0 ORS "\toranges = 3" ORS "\tpears = 2" ORS}
      /\[blk 2\]/{$0 = $0 ORS "\toranges = 5" ORS "\tpears = 2" ORS} 1' sample2.txt
abc
def

    [block 1]
        apples = 3
        grapes = 4

    [blk 2]
        banana = 2
        apples = 3
    oranges = 3
    pears = 2

    oranges = 5
    pears = 2

3 个答案:

答案 0 :(得分:2)

请注意,提供给a command的文字必须在单独的一行:

aaaa
bbbb

并且必须转义所有嵌入的换行符。写它的另一种方式(可能更具可读性):

sed '/\[block 1\]/ {a\
\toranges = 3\n\tpears = 2
}' file

此外,当必须插入大量文本(例如多行)时,请考虑r command作为sed '/\[block 1\]/ {a\ oranges = 3\ pears = 2 }' file 命令的替代。它将从提供的文本文件中读取数据:

a

要使用一个sed '/\[block 1\]/r /path/to/text' file 程序处理多个部分,您可以使用交替运算符(在ERE中可用,请注意sed标志):

-E

答案 1 :(得分:1)

awk应与空RS一起使用。这会将每个块分成一个记录。

awk -v RS= '/\[block 1\]/{$0 = $0 ORS "\toranges = 3" ORS "\tpears = 2" ORS} 
      /\[blk 2\]/{$0 = $0 ORS "\toranges = 5" ORS "\tpears = 2" ORS} 1' file

abc
def
[block 1]
    apples = 3
    grapes = 4
    oranges = 3
    pears = 2

[blk 2]
    banana = 2
    apples = 3
    oranges = 5
    pears = 2

答案 2 :(得分:1)

这可能适合你(GNU sed):

sed '/^\[\(block 1\|blk 2\)\]\s*$/{n;h;s/\S.*/oranges = 5/p;s//pears = 2/p;x}' file

找到所需的匹配项,打印它,然后将下一行存储在保留空间中。将第一个非空格字符替换为第一个必需行的行尾,重复第二个必需字符串,然后恢复为原始行。