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