GNU/Linux >> LINUX-Kenntnisse >  >> Ubuntu

For-Schleife mit Dateinamen?

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 .


Ubuntu
  1. Bash-Datei Massenumbenennung mit Zähler?

  2. Linux + Wie ignoriert (filtert) man Dateien mit Leerzeichen?

  3. Wie suche ich nach Inhalten nach dem Muster?

  4. In .txt-Datei schreiben?

  5. Verschachtelte for-Schleife

Bash For Loop mit praktischen Beispielen

Das mktemp-Befehls-Tutorial mit Beispielen für Anfänger

Das Grep-Befehls-Tutorial mit Beispielen für Anfänger

Bash-Scripting – For-Schleife mit Beispielen erklärt

Bash For-Schleifen mit Beispielen

Bash-Skript für Schleife mit Beispielen erklärt