Vergleichen Sie Dateien anhand von zwei Spalten und fügen Sie ein Feld hinzu

Vergleichen Sie Dateien anhand von zwei Spalten und fügen Sie ein Feld hinzu

Ich habe Dateien mit spaltenweisem Datum und Uhrzeit im Format „JJJJ MM TT HHMM“ plus einer Variable (Temperatur) und möchte diese in das Format JJJJ TTT konvertieren (und Stunde und Temperatur unverändert lassen). Sie sehen so aus, aber dasselbe Datum erscheint mehrmals in der Datei:

1980 01 01 0100 3.3
1982 04 11 0400 2.2
1985 12 04 0700 1.7
1995 12 31 1000 2.2

Ich habe eine Indexdatei (1980-2017) mit der Anzahl der Tage erstellt, die zu jedem Datum der ersten Datei hinzugefügt werden müssen, um den kumulierten Tag des Jahres DDD (letzte Spalte) zu erhalten. Das erste Jahr sieht so aus (1980 war ein Schaltjahr):

1980 01 31  000
1980 02 29  031
1980 03 31  060
1980 04 30  090
1980 05 31  121
1980 06 30  152
1980 07 31  182
1980 08 31  213
1980 09 30  244
1980 10 31  274
1980 11 30  305
1980 12 31  335

Ich versuche, die beiden Dateien anhand der ersten beiden Spalten zu vergleichen und, wenn sie übereinstimmen, die vierte Spalte von Datei 2 zur dritten Spalte von Datei 1 hinzuzufügen. Das Ergebnis könnte ungefähr so ​​aussehen:

1980 001 0100 3.3 
1982 101 0400 2.2 
1985 346 0700 1.7 
1995 365 1000 2.2

Es ist mir gelungen, die beiden Spalten der Dateien zu vergleichen und die beiden Spalten mit awk unten hinzuzufügen:

awk -F' ' 'NR==FNR{c[$1$2]++;next};c[$1$2] > 0' junktemp matrix_sample | awk '{print $1, $3+$4}' 

aber auf diese Weise verliere ich 4 und 5 $ (Stunde und Temperatur). Gibt es eine Möglichkeit, die beiden awk-Funktionen zu kombinieren und im Ergebnis auch 4 und 5 $ von Datei1 zu erhalten? Jede Hilfe ist sehr willkommen.

Antwort1

Es ist schwer zu testen, da Sie nur potenzielle Übereinstimmungen für ein einziges Jahr bereitgestellt haben, aber

awk 'NR==FNR{c[$1$2]=$4; next} ($1$2 in c) {$3 = sprintf("%03d", $3 + c[$1$2])} {print $1, $3, $4, $5}' file2 file1
1980 001 0100 3.3
1982 11 0400 2.2
1985 04 0700 1.7
1995 31 1000 2.2

Antwort2

Unter der Annahme, dass GNU dateund bash(oder eine beliebige Shell, die Prozessersetzung mit durchführt ) und dass die Daten wie in den ersten Beispieldaten in der Frage <(...)in der Datei gespeichert sind :file

$ paste -d ' ' <( date -f <( cut -d ' ' -f1-3 file | tr ' ' '-' ) +"%Y %j" ) \
               <( cut -d ' ' -f4-5 file )
1980 001 0100 3.3
1982 101 0400 2.2
1985 338 0700 1.7
1995 365 1000 2.2
  • Die erste cutwird zusammen mit verwendet, trum die Daten in den ersten drei Spalten der Eingabedaten in die Form umzuwandeln YYYY-MM-DD.
  • Dies wird dateüber die Option an GNU zur Stapelverarbeitung übergeben -f. Als Ausgabe fordern wir Daten im Format an %Y %j. %Yist das Jahr auf dem Formular YYYYund %jist der Tag des Jahres auf dem Formular DDD.
  • Dies wird zusammen mit den letzten beiden Spalten aus der Originaldatei (erstellt durch den zweiten cut) eingefügt, wobei ein einzelnes Leerzeichen als Trennzeichen verwendet wird.

Dies ist eine direkte Transformation von den Originaldaten zum Endergebnis, bei der die von Ihnen erstellte Indexdatei umgangen wird.

verwandte Informationen