Bash sed或awk删除块
我的输入文件有如下块Bash sed或awk删除块,bash,shell,awk,sed,Bash,Shell,Awk,Sed,我的输入文件有如下块 [abc] para1=123 para2=456 para3=111 [pqr] para1=333 para2=765 para3=1345 [xyz] para1=888 para2=236 para3=964 [pqr] para1=tyu para2=ghj para3=ghjk [xyz] para1=qwe para2=asd
[abc]
para1=123
para2=456
para3=111
[pqr]
para1=333
para2=765
para3=1345
[xyz]
para1=888
para2=236
para3=964
[pqr]
para1=tyu
para2=ghj
para3=ghjk
[xyz]
para1=qwe
para2=asd
para3=zxc
现在我需要删除使用sed或awk复制的块。必须删除我们从文件顶部首先得到的块。例:在上述情况下,我们得到的输出如下
[abc]
para1=123
para2=456
para3=111
[pqr]
para1=tyu
para2=ghj
para3=ghjk
[xyz]
para1=qwe
para2=asd
para3=zxc
我确实是通过使用
awk
(不确定您是否忘记了abc
块)得到这个结果的
这将保留每个块的最后一个实例,而不是第一个实例
tac file | awk -F"\n" '!x[$NF]++' RS= ORS="\n\n" | tac
这种方法的一个小问题是,由于字段分隔符是一个换行符,因此行在文本后必须有与作为字段计算的相同数量的空格。否则应该可以完美地工作:)
这也行得通:)我怀疑OP在你发布答案后编辑了他的问题。他想保留副本的最后一个实例,而不是第一个。你应该清楚这是你喜欢的第一个还是最后一个。在我发布帖子后,订单似乎发生了变化:(
$ cat tst.awk
BEGIN{ RS=""; ORS="\n\n" }
!seen[$1]++ { keys[++numKeys] = $1 }
{ rec[$1] = $0 }
END {
for (k=1; k<=numKeys; k++) {
print rec[keys[k]]
}
}
$ awk -f tst.awk file
[abc]
para1=123
para2=456
para3=111
[pqr]
para1=tyu
para2=ghj
para3=ghjk
[xyz]
para1=qwe
para2=asd
para3=zxc
tac file | awk -F"\n" '!x[$NF]++' RS= ORS="\n\n" | tac
tac file | awk '!x[$(NF-1)]++' RS= ORS="\n\n" | tac