搜索一个字符串并替换搜索到的字符串上方的另一个字符串

时间:2019-09-04 04:17:03

标签: shell awk sed

我有一个带有下面几行的文件

ZebraDesigner software

我需要用123 456 123 789 abc efg xyz 搜索,并用abc替换123上方的内容。这是必需的,111只是文件中的一个实例,但是abc可以是多个实例,并且123可以位于123上方的任何位置。 请帮助我。

我已经尝试使用以下sed命令

abc

使用上述命令,它仅替换sed -i.bak "/abc/!{x;1!p;d;};x;s/123/1111" filename ,如果123123上方,如果abc123以上两行,则替换失败了。

5 个答案:

答案 0 :(得分:0)

要做的事情不止于此。这是一个:

sed -i.bak '1{h;d;};/123/{x;p;d;};/abc/{x;s/123/111/;p;d;};H;${x;p;};d' filename

答案 1 :(得分:0)

ed对于脚本中文件的复杂编辑非常有用:

ed -s file <<EOF
/^abc$/;?^123$?;.c
111
.
w
EOF

此:将当前行设置为与abc/^abc$/;)匹配的第一行。然后将匹配123的第一行 更改为111?XXX?向后搜索匹配的正则表达式,然后?^123$?;.选择c c hange一行),最后保存修改后的文件。

答案 2 :(得分:0)

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

sed -Ez 's/(.*)(\n123.*\nabc)/\1\n111\2/' file

这会将文件插入到内存中,并将111插入123之前的最后一次abc之前。

一种不占用大量内存的解决方案:

sed -E '/^123$/{:a;N;/\n123$/{h;s///p;g;s/.*\n//;ba};/\nabc$/!ba;s/^/111\n/}' file

这将在包含123的行之后收集行。如果遇到包含123的另一行,它将卸载之前的所有行,然后再次开始收集行。如果找到包含abc的行,则会在到目前为止收集的行的开头插入111

另一种选择:

sed '/abc/{x;/./{s/^/111\n/p;z};x;b};/123/{x;/./p;x;h;$!d;b};x;/./{x;H;$!d};x' file 

答案 3 :(得分:0)

这是一个经典案例,您要跟踪上一行并在满足当前行的条件下更改重复数据删除。通常,awk程序如下所示:

awk '(FNR==1){prev=$0; next}
     (condition_on_$0) { action_on_prev }
     { print prev; prev = $0 }
     END { print $0 }'

因此,对于OP,它将显示为:

awk '(FNR==1){prev=$0; next}
     $0 == "abc" { if (prev == "123") prev = "111" }
     { print prev; prev = $0 }
     END { print $0 }'

答案 4 :(得分:0)

$ tac file | awk 'f && sub(/123/,"111"){f=0} /abc/{f=1} 1' | tac
123
456
111
789
abc
efg
xyz