Ein Shell-Skript zum Verbinden von zwei Dateien

8

Ich möchte eine schreiben shell script, die zwei Dateien Aund Bund ein Ergebnis wie dieses erhalten:

Datei A:

user_a tel_a addr_a
user_b tel_b addr_b

Datei B:

process_1 user_a
process_2 user_a
process_3 user_b

Und das Ergebnis:

user_a process_1 tel_a addr_a
user_a process_2 tel_a addr_a
user_b process_3 tel_b addr_b

Wie kann ich das machen? awkoder etwas anderes?

Navid Farhadi
quelle
2
Ich denke, es kann nur mit cutund gemacht werden paste, aber ich verstehe die Synthax nicht richtig.
Bernhard
Meine Dateien haben viele Datensätze und Felder, ich kann nicht ausschneiden und einfügen !! Dies ist nur ein Beispiel.
Navid Farhadi
1
@NavidFarhadi nicht ausschneiden und einfügen: Es gibt zwei aktuelle Befehle cutund pastesehen Sie sich deren Handbuchseite an.
Matteo
Ich kann beide Dateien vollständig in den Speicher laden und ich kann auch awk verwenden.
Navid Farhadi
Ich kann auch Perl oder andere verwenden, wenn sie in der Linux-Befehlszeile ausführbar sind.
Navid Farhadi

Antworten:

15

join ...

join -1 2 -2 1 FileB FileA

Ausgabe

user_a process_1 tel_a addr_a
user_a process_2 tel_a addr_a
user_b process_3 tel_b addr_b

Die Eingabedateien müssen nach dem Schlüsselfeld sortiert werden ... Ihre Beispieldateien sind bereits sortiert, sodass keine Notwendigkeit bestand. Andernfalls können Sie die Sortierung wie folgt einfügen.

join -1 2 -2 1 <(sort -k2 FileB) <(sort FileA)
Peter.O
quelle
Was bedeutet die Zahlenparameter?
Navid Farhadi
5
@Navid: Sie können immer die beste und genaueste Beschreibung eines paramaters Befehls an den von beziehen manuell , durch Eingabe man joinin die Befehlszeile des Terminals ... -1 2   -2 1 Mittel: Werden Sie Mitglied auf dem ‚1st-Datei 2.-Feld‘ und die ' 2. Datei 1. Feld '
Peter.O
3

Da joinund pastenicht überall verfügbar sind (sie befinden sich beispielsweise nicht auf meinem BusyBox-basierten System), gehen Sie wie gewünscht mit awk vor:

awk 'BEGIN {
    while( (getline < "fileA") > 0) A[$1]=$2 OFS $3 # read fileA into the array A
    close("fileA")
  } {
    print $2, $1, A[$2]
  }' fileB
zweifelhaft
quelle
Übrigens, Sie haben den Separator verpasst A[$1]=$2 OFS $3... Hier ist eine andere Variante, die die manuelle Schleife in BEGIN vermeidet, aber sie ist ziemlich gleich (zu awk ), obwohl sie einen ansonsten unnötigen Bedingungstest für die zweite Datei einführt: awk 'NR==FNR {A[$1]=$2 OFS $3;next} {print $2, $1, A[$2]}' fileA fileB... (+ 1)
Peter.O