如何使用“sed -e”插入文本

问题描述 投票:0回答:4

例如,我有一个名为test_sed的文件,它的内容是这样的:

abc
def
ghi
jkl

当有三个连续的行像abc\ndef\nghi时,我想插入内容,例如“hello world”。所以我使用sed -f test.sed test_sed。脚本test.sed写如下:

:begin
/abc/,/ghi/ {
  /ghi/! {
    $! {
      N;
      b begin
    }
  }
  /abc.*ghi/a hello world
}

它有效。但是当我在命令行中这样写它:

sed -e ":begin; /abc/,/ghi/ { /ghi/! { $! { N; b begin }; }; /abc.*ghi/a hello world };" test_sed

它不起作用,我不知道如何纠正它。

bash sed
4个回答
0
投票

您应该使用单引号来阻止bash扩展感叹号(!):

sed -e ':begin; /abc/,/ghi/ { /ghi/! { $! { N; b begin }; }; /abc.*ghi/a hello world };' test_sed
       ^                                                                               ^

看起来你需要强行插入一个换行符让sed停止插入,这对我有用:

$ sed -e ':begin; /abc/,/ghi/ { /ghi/! { $! { N; b begin }; }; /abc.*ghi/a hello world
 };' test_sed

0
投票

如果你有perl,那么使用slurp模式就容易多了:

perl -0777 -pe 's~abc\Rdef\Rghi\R~$&hello world\n~' file

abc
def
ghi
hello world
jkl

或者你可以使用awk

awk '$1=="abc"{s=$1; for (i=1; i<=2; i++) {
     getline; s = s RS $1 } if (s=="abc\ndef\nghi") $0 = s RS "hello world"} 1' file

abc
def
ghi
hello world
jkl

0
投票

sed很挑剔。特别是,您似乎使用的版本允许a命令不会立即后跟换行符,因此虽然以下在BSD中有效,但它可能不在gnu-sed上:

$ sed -e ':begin
/abc/,/ghi/ { /ghi/! { $! { N; b begin
}; }; /abc.*ghi/a\
hello world
};' input

0
投票

这可能适合你(GNU sed):

sed '/abc/!b;n;/def/!b;n;/ghi/a\hello world' file

如果第一行包含abc,第二行包含def,第三行包含ghi,然后追加hello world

更强大的解决方案:

sed ':a;N;s/\n/&/2;Ta;/abc.*\n.*def.*\n.*ghi/!P;//!D;a\hello world' file

这允许重试失败。

© www.soinside.com 2019 - 2024. All rights reserved.