sed или awk для удаления блока

#bash #shell #awk #sed

#bash #оболочка #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    
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   
  

Комментарии:

1. Вам должно быть ясно, первое или последнее попадание, которое вам нравится. Похоже, порядок изменился после того, как я опубликовал свой пост: (

Ответ №1:

Я получаю это от использования awk (не уверен, что вы забыли abc блок)

 awk '!a[$1]  ' RS= ORS="nn" file
[abc]
para1=123
para2=456
para3=111

[pqr]
para1=333
para2=765
para3=1345

[xyz]
para1=888
para2=236
para3=964
  

Комментарии:

1. Я подозреваю, что OP отредактировал свой вопрос после того, как вы уже опубликовали ответ. Он хочет сохранить ПОСЛЕДНИЙ экземпляр дубликата, а не первый.

Ответ №2:

 $ cat tst.awk
BEGIN{ RS=""; ORS="nn" }
!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
  

Ответ №3:

Это позволяет сохранить последний экземпляр каждого блока, а не первый

  tac file | awk -F"n" '!x[$NF]  ' RS= ORS="nn"  |  tac
  

Небольшая проблема с этим методом заключается в том, что, поскольку разделителем полей является новая строка, в строках должно быть такое же количество пробелов после текста, какое учитывается как поле.
В противном случае должно работать идеально 🙂

  tac file | awk '!x[$(NF-1)]  ' RS= ORS="nn"  |  tac
  

Это тоже работает 🙂