2017-10-09 3 views
1

Ich versuche, eine Spalte hinzuzufügen, wenn zwei vorherige Felder bereits in einer Datei gefunden wurden.Bash - wenn zwei Spalten übereinstimmen, dann Spalte anhängen

Ich habe eine Komma-getrennte Datei mit einer großen Anzahl von Einträgen und ich muss alle Zeilen finden, die auf zwei Spalten übereinstimmen, die zweite Spalte und die siebte. Wenn beide in mehreren Zeilen gefunden werden, fügen Sie eine achte Spalte hinzu, die "shared" sagt.

Dateiinhalt:

WPC PROD LINUX O,1808,4194304000,10,3G,4G,66314 
WPC PROD LINUX O,1809,3145728000,10,3G,4G,66314 
WPC PROD LINUX O,1812,4194304000,10,3G,4G,66314 
WPC PROD LINUX,1808,4194304000,10,1D,2D,66314 
WPC PROD LINUX,1809,3145728000,10,1D,2D,66314 
WPC PROD LINUX,1812,4194304000,10,1D,2D,66314 
WPCESXCS40BP01_0,1808,4194304000,10,1D,2D,66314 
WPCESXCS40BP01_0,1809,3145728000,10,1D,2D,66314 
WPCESXCS40BP01_0,1812,4194304000,10,1D,2D,66314 

Ausgang gewünscht:

WPC PROD LINUX O,1808,4194304000,10,3G,4G,66314,shared 
WPC PROD LINUX O,1809,3145728000,10,3G,4G,66314,shared 
WPC PROD LINUX O,1812,4194304000,10,3G,4G,66314,shared 
WPC PROD LINUX,1808,4194304000,10,1D,2D,66314,shared 
WPC PROD LINUX,1809,3145728000,10,1D,2D,66314,shared 
WPC PROD LINUX,1812,4194304000,10,1D,2D,66314,shared 
WPCESXCS40BP01_0,1808,4194304000,10,1D,2D,66314,shared 
WPCESXCS40BP01_0,1809,3145728000,10,1D,2D,66314,shared 
WPCESXCS40BP01_0,1812,4194304000,10,1D,2D,66314,shared 

Ich habe gesucht und gefunden diesen Link Awk - matching on 2 columns for differents lines aber es ist nicht ganz das tut, was ich brauche, es passt nur auf den folgenden Linie.

Ich könnte so etwas tun:

while IFS=',' read host device blk poolnum porta portb serial 

    ldev_count=`cat outputtest.txt | grep -iw $device | grep -iw $serial | wc -l` 
    if [[ $ldev_count > 1 ]] ; then 
     echo "$host, $device, $blk, $poolnum, $porta, $portb, $serial, SHARED" >> semifinal.txt 
    else 
     echo "$host, $device, $blk, $poolnum, $porta, $portb, $serial" >> semifinal.txt 
    fi 
done < outputtest.txt 

Aber es ist extrem langsam. Ich hoffe, eine bessere Lösung zu finden.

Danke für jede Hilfe.

+0

Könnten Sie bitte die zweite und die siebte Spalte hier hervorheben, ich meine vielleicht eine gewisse Verwirrung, da ich nicht sehen kann, dass diese 2 Spalten in Ihrer Frage gleich sind? Könnten Sie sie bitte hervorheben? – RavinderSingh13

+0

bearbeitet die Formatierung, um die Lesbarkeit zu verbessern. –

+0

Ok, Sie sagen also, wenn die Spalten '2 & 7' zwischen zwei beliebigen Zeilen geteilt werden (zB' 1808' und '66314'), möchten Sie' 'shared" 'an das Ende beider gemeinsamer Zeilen anhängen ? –

Antwort

3

Sie könnten dies benötigen:

awk -F\, 'NR==FNR{a[$2]++;b[$7]++;next} 
      a[$2]>1 && b[$7]>1{$(NF+1)="shared"}1' OFS=',' file file 

Ergebnis:

WPC PROD LINUX O,1808,4194304000,10,3G,4G,66314,shared 
WPC PROD LINUX O,1809,3145728000,10,3G,4G,66314,shared 
WPC PROD LINUX O,1812,4194304000,10,3G,4G,66314,shared 
WPC PROD LINUX,1808,4194304000,10,1D,2D,66314,shared 
WPC PROD LINUX,1809,3145728000,10,1D,2D,66314,shared 
WPC PROD LINUX,1812,4194304000,10,1D,2D,66314,shared 
WPCESXCS40BP01_0,1808,4194304000,10,1D,2D,66314,shared 
WPCESXCS40BP01_0,1809,3145728000,10,1D,2D,66314,shared 
WPCESXCS40BP01_0,1812,4194304000,10,1D,2D,66314,shared 

Erklärung

wir die Datei iterieren fahren zweimal:

Erste: NR==FNR{a[$2]++;b[$7]++;next}

Wir bekommen die Wiederholungen jeder Spalte und speichern sie in a und b Arrays.

Zweite: a[$2]>1 && b[$7]>1{$(NF+1)="shared"}1

den Zeilen zu filtern, die die Anzahl der Wiederholungen entsprechen, die Sie erwarten, muss diese Zahl größer als eine für beide Spalten, um eine neue Endung Spalte hinzuzufügen: $(NF+1)="shared".

Hinweis: 1 ist nur eine Verknüpfung, um die Verwendung der print-Anweisung zu vermeiden.

+0

Das ist perfekt! Tausend Dank! –

2

Könnten Sie bitte versuchen Sie es bearbeitet für die Formatierung von folgenden und lassen Sie mich wissen, ob das Ihnen hilft.

awk -F, 'FNR==NR{a[$2,$7]++;next} a[$2,$7]>1{print $0",shared"}' Input_file Input_file 

Die Ausgabe wird wie folgt sein.

WPC PROD LINUX O,1808,4194304000,10,3G,4G,66314,shared 
WPC PROD LINUX O,1809,3145728000,10,3G,4G,66314,shared 
WPC PROD LINUX O,1812,4194304000,10,3G,4G,66314,shared 
WPC PROD LINUX,1808,4194304000,10,1D,2D,66314,shared 
WPC PROD LINUX,1809,3145728000,10,1D,2D,66314,shared 
WPC PROD LINUX,1812,4194304000,10,1D,2D,66314,shared 
WPCESXCS40BP01_0,1808,4194304000,10,1D,2D,66314,shared 
WPCESXCS40BP01_0,1809,3145728000,10,1D,2D,66314,shared 
WPCESXCS40BP01_0,1812,4194304000,10,1D,2D,66314,shared 

EDIT: Wenn Sie mit String-Matching-Linien drucken möchten "shared" und nicht passenden Linien einfach drucken Sie dann folgenden können Sie in derselben helfen.

awk -F, '   ##Creating field delimiter as comma. 
FNR==NR{   ##FNR==NR is a condition which will be TRUE when first Input_file is being read. 
    a[$2,$7]++;  ##creating an array named a whose index is $2,$7(second and 7th field) and incrementing its value with 1 each time same elements come. 
    next    ##Using next keyword will skip all further statements. 
} 
a[$2,$7]>1{   ##This condition will be TRUE only when 2nd Input_file is being read, check if array a value in index of $2,$7 is greater than 1. 
    print $0",shared" ##Printing the current line with keyword shared at last of line. 
    next; 
} 
1 
' Input_file Input_file ##Mentioning the Input_file twice here. 
+0

das macht genau das, wonach ich gefragt habe. Gibt es eine Möglichkeit, auch nicht übereinstimmende Zeilen zu drucken? –

+0

@LukeFowler, können Sie bitte meine Bearbeitungslösung überprüfen und lassen Sie mich wissen, ob dies Ihnen hilft. – RavinderSingh13

Verwandte Themen