Ich habe mehrere Dateien (Tabellen) mit dem Namen:institute _
Modell _
Szenario _
Fluss .txt
(Institut , Modell , Szenario , und Fluss sind Variablen.) Ich möchte einen for
erstellen Schleife, die alle Dateien identifiziert, die dasselbe Institut haben Namen und gleichzeitig dasselbe Szenario Name, um die Ergebnisse jedes unterschiedlichen Modells anzuhängen in derselben Ausgabedatei mit dem folgenden Befehl:
paste filename1.txt filename2.txt > output_file.txt
Ich weiß, wie man einen for
erstellt Schleife über verschiedene Ordner, aber nicht über Dateinamen. Hat jemand eine Idee?
Als Minimalbeispiel könnten die Dateinamen wie folgt lauten:
wbm_gfdl_rcp8p5_mississippi.txt
wbm_hadgem_rcp8p5_mississippi.txt
matsiro_gfdl_rcp8p5_mississippi.txt
matsiro_ipsl_rcp4p5_mississippi.txt
matsiro_hadgem_rcp4p5_mississippi.txt
matsiro_miroc_rcp8p5_mississippi.txt
Dann möchte ich die folgenden Dateien zusammen anhängen:
wbm_gfdl_rcp8p5_mississippi.txt with
wbm_hadgem_rcp8p5_mississippi.txt
matsiro_ipsl_rcp4p5_mississippi.txt with
matsiro_hadgem_rcp4p5_mississippi.txt
matsiro_gfdl_rcp8p5_mississippi.txt with
matsiro_miroc_rcp8p5_mississippi.txt
Akzeptierte Antwort:
Wenn sich die Dateien alle im selben Verzeichnis befinden, können Sie:
ls |
awk -F_ '{ i=$1; m=$2; s=$3; f[i"_"s] = f[i"_"s] " " $0 }
END{ for(insc in f)
printf "paste%s >out_%s.txt\n",f[insc],insc
}'
wodurch der Dateiname auf „_“ aufgeteilt wird (-F_
), setzt die Variablen i,m,s
auf die ersten 3 Teile des Dateinamens (Institut, Modell, Szenario),
und akkumuliert im Array des Dateinamens. Das Array wird
nur vom Institut und Szenario indiziert, sodass alle Modelle verkettet werden
(m wird nicht verwendet). Das abschließende END gibt das f-Array aus und verwendet den Index (institute_scenario) als
Namen für die Ausgabedatei. Mit Ihren Beispielen ergibt dies
paste wbm_gfdl_rcp8p5_mississippi.txt wbm_hadgem_rcp8p5_mississippi.txt >out_wbm_rcp8p5.txt
paste matsiro_hadgem_rcp4p5_mississippi.txt matsiro_ipsl_rcp4p5_mississippi.txt >out_matsiro_rcp4p5.txt
paste matsiro_gfdl_rcp8p5_mississippi.txt matsiro_miroc_rcp8p5_mississippi.txt >out_matsiro_rcp8p5.txt
Sie müssen dies dann in die Shell leiten, damit es ausgeführt wird. Fügen Sie | sh
in die letzte Zeile oben, um dies zu tun.
Um einige Spalten aus den Eingabedateien zu entfernen, müssen Sie die awk-Zeile
ändern, die alle Eingabedateinamen sammelt. In der 1. awk-Zeile:
{ i=$1; m=$2; s=$3; f[i"_"s] = f[i"_"s] " " $0 }
der Dateiname ist „$0“. Wenn Sie diese Zeile beispielsweise ändern in:
{ i=$1; m=$2; s=$3; f[i"_"s] = f[i"_"s] sprintf(" <(cut -f4 %s)",$0) }
dann erhalten Sie die Beispielausgabe:
paste <(cut -f4 wbm_gfdl_rcp8p5_mississippi.txt) <(cut -f4 wbm_hadgem_rcp8p5_mississippi.txt) >out_wbm_rcp8p5.txt
aber wenn du nur den 2. Dateinamen ausschneiden willst, ist es etwas komplizierter und
brauchst du stattdessen das:
{ i=$1; m=$2; s=$3;
if(f[i"_"s]=="")add = $0; else add = sprintf("<(cut -f4 %s)",$0);
f[i"_"s] = f[i"_"s] " " add }
so erhalten Sie
paste wbm_gfdl_rcp8p5_mississippi.txt <(cut -f4 wbm_hadgem_rcp8p5_mississippi.txt) >out_wbm_rcp8p5.txt
Wenn sh
versteht die Syntax <(cut ...)
nicht dann ersetzen Sie es durch bash
.