替换2个匹配单词之间的所有行

时间:2019-03-31 13:33:11

标签: linux awk sed

我有两个文件;

in1.txt

bbb
ccc
ddd
aaa
ccc
bbb
ddd

in2.txt

sss

in1.txt中,我想用aaa的内容替换从dddin2.txt第一次出现的行。

所需的输出

bbb
ccc
ddd
sss

3 个答案:

答案 0 :(得分:2)

tl; dr:

$ sed -e "/aaa/,/ddd/c\\$(cat in2.txt)" in1.txt
bbb
ccc
ddd
sss

详细信息:

$ sed -e '/START/,/FIN/c\REPLACE_WITH' file

/START/,/FIN/表示要替换的文本范围-以START开头,以FIN结尾。
\c用于将先前声明的行替换为REPLACE_WITH

希望这会有所帮助。

答案 1 :(得分:1)

这可能对您有用(GNU sed):

sed -e 'x;/x/{x;:a;n;ba};x;/^aaa$/{:b;N;/^ddd$/M!bb;x;s/^/x/;x;r file2' -e 'd}' file1

为了只进行一次替换,请在保留空间中设置一个标志,并在每次读入一行时检查是否已设置该标志。如果有,请使用n命令和循环来打印文件的其余部分。

如果未设置标志,则在遇到开始定界符时,将文件累积到模式空间中的结束定界符。设置一次标志,并读入第二个文件的内容。最后删除模式空间。

答案 2 :(得分:0)

在提供的不错的sed解决方案的基础上,我添加了一个awk

输入文件:

$ more in*.txt
::::::::::::::
in1.txt
::::::::::::::
bbb
ccc
ddd
aaa
ccc
bbb
ddd
::::::::::::::
in2.txt
::::::::::::::
sss

命令:

awk -v delim1="aaa" -v delim2="ddd" -v target=in2.txt '{if($0 == delim1){test=1;system("cat "target);next}if(test !=1) print;if($0 == delim2){test=0};}' in1.txt

输出:

bbb
ccc
ddd
sss

代码:

{
 if ($0 == delim1) {
  test = 1
  system("cat " target)
  next
 }
 if (test != 1) {
  print $0
 }
 if ($0 == delim2) {
  test = 0
 }
}

说明:

  1. -v delim1="aaa" -v delim2="ddd" -v target=in2.txt,您将两个定界符作为参数以及要从(awk)中读取的文件传递给in2.txt

  2. 到达第一个定界符时,test变量将设置为1,并且打印in2.txt的内容,然后跳到下一行。

  3. 如果test变量与1不同,则打印行(这意味着您尚未遇到第一个定界符)

  4. 到达第二个定界符时,您将重置test以允许打印文件的其余部分。