2016-03-29 6 views
0

Ich freue mich immer über Ihre Hilfe.Löschen von Zeilen, die duplizierte Zeichenfolgen enthalten

Ich möchte Zeilen mit doppelten Strings in der zweiten Spalte löschen.

test.txt

658 invert_d2e_q_reg_0_/Qalu_ecl_zlow_e 0.825692 
659 invert_d2e_q_reg_0_/Qalu_byp_rd_data_e[31] 0.825692 
660 invert_d2e_q_reg_0_/Qalu_byp_rd_data_e[63] 0.825692 
661 invert_d2e_q_reg_0_/Qalu_ecl_zhigh_e 0.825692 
665 invert_d2e_q_reg_0_/Qalu_byp_rd_data_e[62] 0.825692 
666 invert_d2e_q_reg_0_/Qalu_ecl_zlow_e 0.825692 
668 invert_d2e_q_reg_0_/Qalu_ecl_zhigh_e 0.825692 
670 invert_d2e_q_reg_0_/Qalu_ecl_zhigh_e 0.825692 
673 invert_d2e_q_reg_0_/Qalu_ecl_zlow_e 0.825692 
675 invert_d2e_q_reg_0_/Qalu_ecl_zhigh_e 0.825692 
677 invert_d2e_q_reg_0_/Qalu_ecl_zhigh_e 0.825692 
678 invert_d2e_q_reg_0_/Qalu_byp_rd_data_e[27] 0.825692 
679 invert_d2e_q_reg_0_/Qalu_byp_rd_data_e[27] 0.8120 
. 
. 
. 

output.txt

658 invert_d2e_q_reg_0_/Qalu_ecl_zlow_e 0.825692 
659 invert_d2e_q_reg_0_/Qalu_byp_rd_data_e[31] 0.825692 
660 invert_d2e_q_reg_0_/Qalu_byp_rd_data_e[63] 0.825692 
661 invert_d2e_q_reg_0_/Qalu_ecl_zhigh_e 0.825692 
665 invert_d2e_q_reg_0_/Qalu_byp_rd_data_e[62] 0.825692 
678 invert_d2e_q_reg_0_/Qalu_byp_rd_data_e[27] 0.825692 
. 
. 
. 

weiß ich sed Linien mit vordefinierten spezifischen Strings löschen können, aber in meinem Fall konnte ich nicht erwartet, die Saiten dupliziert werden. Doppelte Zeichenfolgen können auch mehr als 1000 sein.

Ich habe "uniq" verwendet, um diese Aufgabe zu erledigen, aber das funktioniert nicht. uniq -u -f 4 test.txt (-u druckt einzigartige Linien. -f die ersten 4 Buchstaben überspringt.)

Gibt es eine Möglichkeit, dies zu tun mit sed/awk/perl? Oder korrigiere bitte meine uniq-Semantik.

Best,

Jaeyoung

+0

'man sort': schau dir die' -u' Option an. Sie müssen einen Schlüssel angeben, vielleicht "-k2". Viel Glück. – shellter

+1

'uniq' muss mit sortierter Eingabe arbeiten. Also benutze 'sort -k4 | uniq -u -f4' – Will

+1

'awk' mit Arrays sollte dies schnell machen. –

Antwort

1

Dies könnte für Sie arbeiten (GNU sed):

sed -r 'G;/^\S+\s+(\S+)\s+.*\n.*\1/!{P;s/\S+\s+(\S+)\s+.*/\1/;H};d' file 

Test, um die zweite Säule gegen alle eindeutigen Werte dieser Spalte im Raum halten gespeichert (HS) und wenn nicht vorhanden, drucken Sie die Linie und speichern Sie ihren Wert im HS.

Oder verwenden sort:

sort -suk2,2 file | sort -nk1,1 
+0

Elegante Wege. +1 –

0

Awk würde dies mit einem Werkzeug, aber hier ist ziemlich einfach, wie es mit Bash assoziativer Arrays zu tun. Überstreichen Sie die Zeilen und ziehen Sie die dritte Spalte heraus. Wenn kein assoziativer Array-Eintrag vorhanden ist, geben Sie ein Echo für die Linie ein und legen Sie einen Wert fest, damit sie nicht weiter gedruckt wird.

unset col3 && declare -A col3 && IFS=$(echo -en "\n\b") && for a in $(< test.txt); do 
lncol3=$(echo "${a}" | tr '/' ' ' | awk '{print $3}') 
[[ -z "${col3["${lncol3}"]}" ]] && echo "${a}" && col3["${lncol3}"]=1 
done 
+0

Dies ist eine nützliche Technik zu wissen, aber 'sort -uk2,2 test.txt | sort' erledigt die Aufgabe präzise. –