我有一个带有下面几行的文件
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
,如果123
在123
上方,如果abc
在123
以上两行,则替换失败了。
答案 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