Ich habe folgende Datei:
cat fileA.txt
seattle 1991 west
atlanta 1993 west
turlock 1998 west
marysville 2004 south
newyork 2007 north
canada 2004 west
Und die zweite Datei sieht so aus:
cat fileB.txt
popular
someWhatPopular
boring
popular
popular
popular
Ich möchte folgende Ausgabe erhalten fileB.txt
:
popular popular popular someWhatPopular boring popular
Im Wesentlichen versuche ich also, fileB.txt
in fileA.txt
die dritte Spalte zu sortieren
Ich habe den folgenden Code ausprobiert:
#!/bin/bash
sort -s -k3,3 fileA.txt fileB.txt
Aber es hat nicht funktioniert. Irgendwelche Vorschläge? Ich bin ziemlich offen für alles, was keine Hardcoding erfordert. Bash/awk/sed usw.
Antwort1
Dies ist eher ein Datenstrukturproblem als ein Linux-Problem. Sie benötigen einen gemeinsamen Eintrag (Schlüssel) in beiden Tabellen, um sie zu verknüpfen, genau wie in jeder „Datenbank“, und es empfiehlt sich, in der ersten Spalte jeder Datentabelle einen eindeutigen Schlüssel zu speichern. Dann können Sie nach Herzenslust sortieren und verknüpfen.
Nehmen Sie beispielsweise @glennjackman mapping und definieren Sie den Zuordnungsschlüssel als Nord, Süd usw.
1 south somewhatPopular
2 west popular
3 north boring
4 east unexplored
in einer Datei namens file popularity
. Ändern Sie es, fileA
um einen eindeutigen Schlüssel einzuschließen
1 seattle 1991 west
2 atlanta 1993 west
3 turlock 1998 west
4 marysville 2004 south
5 newyork 2007 north
6 canada 2004 west
dann können Sie diese Dateien bearbeiten, indem join
Sie sie auf den von Ihnen gewählten Schlüssel (in Ihrem Fall wird Spalte 2 in popularity
Spalte 4 in zugeordnet fileA
) sortieren, aber join
beide Dateien müssen auf dem Schlüsselfeld sortiert sein, also
join -1 4 -2 2 <(sort -k4 fileA) <(sort -k2 popularity) | sort -k2 | awk '{print $6}'
popular
popular
popular
somewhatPopular
boring
popular
Dies ist ein bisschen ein Vorschlaghammer-Ansatz, der Ihnen aber die größte Flexibilität bietet.
Unterbrechen Sie den obigen Befehl an jeder Pipe und Sie werden sehen, was jeder Schritt bewirkt.
Bearbeiten: Erklärung vonjoin -1 4 -2 2 # its in the man pages
Dies weist darauf hin join
, dass man in der 4. Spalte der Tabelle 1 (-1 4) nachsehen und in der 2. Spalte der Tabelle 2 (-2 2) nach passenden Werten suchen soll.
join
dann werden die Spalten aus den beiden Tabellen zu einer einzigen Tabelle zusammengefasst, wobei die Schlüsselspalte (Norden usw.) nur einmal eingefügt wird. Sehen Sie sich die Ausgabe von
join -1 4 -2 2 <(sort -k4 fileA) <(sort -k2 popularity)
und es sollte klarer sein
Da wir die Datentabellen sortieren mussten, damit das join
funktionierte, haben wir dann
| sort -k2
die kombinierte Tabelle, um sie wieder in ihre ursprüngliche Reihenfolge zu bringen.
Die gewünschte Spalte ist Spalte 6 in der kombinierten Tabelle, also müssen wir nur
| awk '{print $6}'
zu stdout.
Antwort2
Sie könnten versuchen, paste
die beiden „Tabellen“-Dateien zusammenzufassen, die Ausgabe an weiterzuleiten sort
und dann cut
nur die vierte Spalte beizubehalten.
Ungetesteter (im Moment noch mit dem Handy) Versuch wäre so etwas wie
paste fileA fileB | sort -s -k3,3 | cut -f4
Antwort3
Die alphabetische Zuordnung erhalten Sie mit
paste <(awk '{print $NF}' fileA.txt | sort -u) <(sort -u fileB.txt)
north boring
south popular
west someWhatPopular
Und dann kann mit awk eine Form der gewünschten Ausgabe erzeugt werden:
awk '
NR==FNR {map[$1] = $2; next}
{print map[$NF]}
' <(paste <(awk '{print $NF}' fileA.txt | sort -u) <(sort -u fileB.txt)) fileA.txt
someWhatPopular
someWhatPopular
someWhatPopular
popular
boring
someWhatPopular