Wie kann ich in awk/shell zwei Dateien mit demselben Datensatz zeilenweise zusammenführen?

Wie kann ich in awk/shell zwei Dateien mit demselben Datensatz zeilenweise zusammenführen?

Ich bin neu bei awk und Shell und frage mich, wie ich mit Shell/awk zwei Dateien mit der Zeile zusammenführen kann, die denselben Datensatz haben? Datei1 und Datei2 können eine unterschiedliche Reihenfolge für den Namen haben. Ich möchte nur die Zeilen zusammenführen, die denselben Datensatz haben. Bitte helfen Sie.

file1.txt
Mary 68 
Tom 50 
Jason 45
Lu 66

file2.txt
Jason 37
Tom 26
Mary 74
Tina 80

mergefile.txt
Marry 68 74
Tom 50 26
Jason 45 37 

Ich habe awk ausprobiert, aber es dauert eine Weile, bis das Skript ausgeführt wird. Ich frage mich, ob es eine schnellere und einfachere Implementierung geben könnte.

cat file1.txt | while read line
do
    score1=$( echo $line | awk '{print $2}');
    name1=$( echo $line | awk '{print $1}');

    cat file2.txt | while read l
    do
        score2=$( echo $l | awk '{print $2}');
        name2=$( echo $l | awk '{print $1}');
        if [[ $name1 == $name2 ]]
        then
            echo "$name1 $score1 $score2" >> mergefile
            break
        fi
    done
done

Antwort1

Wenn Sie awk verwenden möchten:

$ awk 'NR==FNR {a[$1] = $2; next} $1 in a {print $1, $2, a[$1]}' file2.txt file1.txt 
Mary 68 74
Tom 50 26
Jason 45 37

Es ist keine Sortierung erforderlich und die Ausgabe erfolgt in der Reihenfolge der zweiten angegebenen Datei.

Erläuterung:

  • NR==FNRist die kanonische Methode, Datensätze aus der ersten benannten Datei auszuwählen
  • {a[$1] = $2; next}Füllen Sie ein Array mit Schlüsseln aus dem ersten Feld und Werten aus dem zweiten
  • $1 in awenn das erste Feld bereits in der ersten Datei vorhanden war; dann
  • {print $1, $2, a[$1]}Drucken Sie den Schlüssel und den Wert aus der zweiten Datei und den Wert aus der ersten

Antwort2

Das klingt nach einem Job fürjoin, der relationale Datenbankoperator

join <(sort file1.txt) <(sort file2.txt)

Tests

$ cat file1.txt
Mary 68
Tom 50
Jason 45
Lu 66

$ cat file2.txt
Jason 37
Tom 26
Mary 74
Tina 80

$ join <(sort file1.txt) <(sort file2.txt)
Jason 45 37
Mary 68 74
Tom 50 26

joinist ein in POSIX angegebenes Standardwerkzeug.

Auf der joinManpage heißt es:

The files file1 and file2 shall be ordered in the collating sequence of sort -b on the 
fields on which they shall be joined, by default the first in each line. All selected 
output shall be written in the same collating sequence.

verwandte Informationen