2016-06-09 34 views
1

ich eine Textdatei namens „hosts.tbl“:AIX grep für ein awk Ergebnis

BILL RED 
VAL YELLOW 
STEVE YELLOW 
TOM ORANGE 
BILLY RED 
VALERIE BLUE 

Ich habe eine zweite Datei mit dem Namen „details.tbl“, die jeden Namen oben hat, mehrere Male (unter verschiedenen anderen Details in jeder Zeile). Ich brauche zu zählen, wie oft jeder Namen erscheint in „details.tbl“, und mit etwas am Ende wie folgt:

BILL RED 8 
VAL YELLOW 16 
STEVE YELLOW 9 
TOM ORANGE 1 
BILLY RED 2 
VALERIE BLUE 30 

Wie Sie sehen können, einen normalen „grep“ für ‚Bill‘ wird mich beide "BILL" und "BILLY". Gleiches gilt für "VAL" und "VALERIE". Innerhalb der Datei "details.tbl" folgt auf jedes Vorkommen jedes Namens jedoch "-C". Zum Beispiel:

STEVE-C 
STEVE-C 
BILL-C 
BILLY-C 

Ich habe versucht:

awk {'print $1 " " $2 " "'} hosts.tbl|grep -c $1"-C" details.tbl 
awk {'print $1 " " $2 " "'grep -c $1"-C" details.tbl} hosts.tbl 

... und verschiedene andere Permutationen ähnlicher Syntax, oben ... alle düsteren Ausfälle. Klar, ich bin ein Neuling, wenn es um Shell-Befehle im Besonderen und UNIX im Allgemeinen geht. Was fehlt mir hier? Ich kann nichts in den man-Seiten finden, wie Suchkriterien in grep verkettet werden oder wie nur bestimmte Felder von awk an grep übergeben werden.

den anwendbaren Teil der details.tbl Datei sieht wie folgt aus der Annahme:

BILL-C 
VAL-C 
STEVE-C 
TOM-C 
BILLY-C 
VALERIE-C 
BILL-C 
VAL-C 
STEVE-C 
TOM-C 
BILLY-C 
VALERIE-C 

Die Ausgabe sollte wie folgt aussehen:

BILL RED 2 
VAL YELLOW 2 
STEVE YELLOW 2 
TOM ORANGE 2 
BILLY RED 2 
VALERIE BLUE 2 
+1

Es ist nicht klar, ob Sie denken, BILL und BILLY (zum Beispiel) ist das, was Sie brauchen. Gegeben sei deine '-C' Datei, bitte ** editiere deine Q ** um die erwartete Ausgabe für einen der 2 Einträge zu zeigen. (Obwohl dies in diesem Fall nicht notwendig ist, ist es eine gute Idee, weiterhin Ihre AIX Qs als solche zu kennzeichnen, da sich dieses System sehr von Linux unterscheidet, und sogar von anderen Anbietern im alten Stil Unixens). Viel Glück. – shellter

+0

Anders erklärt (wenn ich das gut verstehe): Ich habe eine Datei 'hosts.tbl' mit Vor- und Nachnamen. Eine andere Datei 'details.tbl' hat nur die Vornamen, gefolgt von' -C'. Alle Vornamen in 'hosts.tbl' sind eindeutig. Ich möchte alle Vornamen zählen und ihnen ihren Nachnamen geben. –

Antwort

1

Katze hosts.tbl

BILL RED 
VAL YELLOW 
STEVE YELLOW 
TOM ORANGE 
BILLY RED 
VALERIE BLUE 

Katze Details.tbl

BILL RED 
VAL YELLOW 
STEVE YELLOW 
TOM ORANGE 
BILLY RED 
VALERIE BLUE 
BILL RED 
VAL YELLOW 
STEVE YELLOW 
TOM ORANGE 
BILLY RED 
VALERIE BLUE 
BILL RED 
VAL YELLOW 
STEVE YELLOW 
TOM ORANGE 

mit awk Befehl erhalten wir den Namen aus der 1. Datei und speichern Sie in Array ein, vom 2.-Datei wir übereinstimmen, wenn der Name vorhanden ist, und wenn ja, wird der Zählwert erhöht

awk 'FILENAME == ARGV[1]{a[$0]=0;next} FILENAME == ARGV[2] && $0 in a{a[$0]+=1} END 
{for(i in a){print i,a[i]}} ' hosts.tbl details.tbl 

Ausgabe

VALERIE BLUE 2 
BILLY RED 2 
BILL RED 3 
VAL YELLOW 3 
TOM ORANGE 3 
STEVE YELLOW 3 
1

Wenn Sie https://unix.stackexchange.com/a/169765/57293 ignorieren können Sie mak e eine Lösung wie

while read -r name lastname ; do 
    printf "%s %s %s\n" ${name} ${lastname} $(grep -c "${name}-C" details.tbl) 
done < hosts.tbl 

Wenn Sie awk verwenden, sollten Sie zunächst Prozess details.tbl und die Linien zählen. Die Verarbeitung von 2 Dateien in einem Awk-Skript wird unter What is "NR==FNR" in awk? erläutert.
Sie wollen die -C zu ignorieren, Sie Vorprozess die Eingabedatei mit cut wie diese können:

awk 'NR==FNR {a[$0]++;next} { 
     for(i in a) { 
     if ($1==i) { 
      print $0, a[i] 
     } 
     } 
    }' <(cut -d"-" -f1<details.tbl) hosts.tbl 

awk smart ist, wird die Vorverarbeitung mit Schnitt nicht benötigt:

awk -F '[ -]' 'NR==FNR {a[$1]++; next} { 
     for(i in a) { 
     if ($1==i) { 
      print $0, a[i] 
     } 
     } 
    }' details.tbl hosts.tbl