击:如何用sed在文件中只替换最后一次出现?(Bash: how to use sed to rep

2019-09-16 11:24发布

有一个文件,其中包含重复的注释行,如:

# ScriptAlias /cgi-bin/ "somepath"
# ScriptAlias /cgi-bin/ "otherpath"

我想补充导致最后一次出现后,才一行

# ScriptAlias /cgi-bin/ "somepath"
# ScriptAlias /cgi-bin/ "otherpath"
ScriptAlias /cgi-bin/ "mypath"

要做到这一点我使用这个命令:

sed -i 's:^\(.*ScriptAlias /cgi-bin/.*\):\1 \nScriptAlias /cgi-bin/ "mypath":' file

但是,这会导致增加我行像每次出现后:

# ScriptAlias /cgi-bin/ "somepath"
ScriptAlias /cgi-bin/ "mypath"
# ScriptAlias /cgi-bin/ "otherpath"
ScriptAlias /cgi-bin/ "mypath"

我怎么能告诉sed只替换最后一次出现?

编辑:
如果没有办法使用SED解决它(如在评论说的),请提供备选方案达到相同的结果,谢谢。



编辑
重复的线路可以与他们之间的其他线路等separeted

# ScriptAlias /cgi-bin/ "somepath"
# ScriptAlias /cgi-bin/ "otherpath"

# ScriptAlias /cgi-bin/ "another-path"
ScriptAlias /foo/ "just-jump"
# ScriptAlias /cgi-bin/ "that's the last"

Answer 1:

使用TAC所以您打印新的生产线在第一时间看到的模式:

tac file | awk '/ScriptAlias/ && ! seen {print "new line"; seen=1} {print}' | tac


Answer 2:

替代使用awk:

awk '/ScriptAlias \/cgi-bin\//{x=NR} {a[NR]=$0;}END{for(i=1;i<=NR;i++){if(i==x+1)print "$$$here comes new line$$$"; print a[i];}}' file

测试:

kent$  echo "# ScriptAlias /cgi-bin/ "somepath"
fooo
# ScriptAlias /cgi-bin/ "otherpath"
bar
"|awk '/ScriptAlias \/cgi-bin\//{x=NR} {a[NR]=$0;}END{for(i=1;i<=NR;i++){if(i==x+1)print "$$$here comes new line$$$"; print a[i];}}'

输出:

# ScriptAlias /cgi-bin/ somepath
fooo
# ScriptAlias /cgi-bin/ otherpath
$$$here comes new line$$$
bar


Answer 3:

tail -r temp | awk '{line="yourline"}{if($0~/ScriptAlias/&&last==0){print line"\n"$0;last=1}else print}' | tail -r

下面的测试:

krithika.337> cat temp
# ScriptAlias /cgi-bin/ "somepath" 
# ScriptAlias /cgi-bin/ "otherpath" 
# ndmxriptAlias /cgi-bin/ "otherpath" 
# ScriptAlias /cgi-bin/ "otherpath" 
# bdjiptAlias /cgi-bin/ "otherpath" 
krithika.338> tail -r temp | awk '{line="yourline"}{if($0~/ScriptAlias/&&last==0){print line"\n"$0;last=1}else print}' | tail -r
# ScriptAlias /cgi-bin/ "somepath" 
# ScriptAlias /cgi-bin/ "otherpath" 
# ndmxriptAlias /cgi-bin/ "otherpath" 
# ScriptAlias /cgi-bin/ "otherpath" 
yourline
# bdjiptAlias /cgi-bin/ "otherpath" 
krithika.339>


Answer 4:

这是编辑的任务。

ex input_file << "DONE"
/ScriptAlias \/cgi-bin\/ "otherpath"
a
ScriptAlias /cgi-bin/ "mypath"
.
:1
/ScriptAlias \/cgi-bin\/ "another-path"
a
ScriptAlias /cgi-bin/ "just-jump"
.
:x
DONE

在最后一次出现的模式。

ex input_file << "DONE"
$
?ScriptAlias \/cgi-bin\/ "otherpath"
a
ScriptAlias /cgi-bin/ "mypath"
.
$
?ScriptAlias \/cgi-bin\/ "another-path"
a
ScriptAlias /cgi-bin/ "just-jump"
.
:x
DONE


文章来源: Bash: how to use sed to replace only the last occurence in a file?