For-Schleife zum Durchlaufen des Verzeichnisbaums und Extrahieren von Ergebnissen aus Dateien mit demselben Namen

For-Schleife zum Durchlaufen des Verzeichnisbaums und Extrahieren von Ergebnissen aus Dateien mit demselben Namen

Ich habe eine Reihe von Verzeichnissen, alle im list.txtgleichen Format, und ich möchte die Ergebnisse in einer einzigen Datei speichern. Ich möchte ein Skript schreiben, das sich iterativ durch jeden Verzeichnisbaum bewegt, list.txtmithilfe der unten stehenden grep/awk-Pipeline eine bestimmte Spalte aus der Datei ohne umgebenden Text extrahiert und die Ausgaben jedes einzelnen in dieselbe Datei schreibt.

    grep 'bar[0-9]' file.txt | awk '{print $1}'

Ich habe Folgendes versucht, bin mir aber nicht sicher, wo genau meine Schleifen im Skript falsch laufen.

#!/bin/bash
##Extract ligands from toplist and concatenate to file
for i in /home/ubuntu/Project/working/library_*/Results/list.txt
do
    grep 'bar[0-9]' i | awk '{print $1}' | cat ../output.txt i
done

Der Verzeichnisbaum sieht wie folgt aus:

.
├── library_1-200
│   ├── Results
│   │   ├── complex
│   │   ├── sorted.txt
│   │   └── list.txt
│   ├── files
│   │   ├── output
│   │   └── txt
│   └── summary.txt
├── library_201-400
│   ├── Results
│   │   ├── complex
│   │   ├── sorted.txt
│   │   └── list.txt
│   ├── files
│   │   ├── output
│   │   └── txt
│   └── summary.txt
├── library_401-600
│   ├── Results
│   │   ├── complex
│   │   ├── sorted.txt
│   │   └── list.txt
│   ├── files
│   │   ├── output
│   │   └── txt
│   └── summary.txt
└── library_601-800
    ├── Results
    │   ├── complex
    │   ├── sorted.txt
    │   └── list.txt
    ├── files
    │   ├── output
    │   └── txt
    └── summary.txt

Beispiel für list.txt, wo ich nur die NameWerte einfügen möchteoutput.txt

Name    Score
bar65    -7.8 
bar74    -7.5 
bar14    -7.5 
bar43    -7.4 
bar94    -7.4 
bar16    -7.4 
bar12    -7.3 
bar25    -7.3 
bar65    -7.3 
bar76    -7.3 
bar24    -7.3 
bar13    -7.3 
bar58    -7.2 
bar68    -7.2 
bar28    -7.2 

Die Lösung bestand darin, "$i" dort einzufügen, wo vorher nur i stand, und es zu ändern in| cat >> ../output.txt

Antwort1

Sie verwenden ianstelle dieser Verwendung $iim grep-Befehl.

Und Sie sagten, dass Sie sie alle in einer einzigen Datei bündeln möchten. Dann sollte der letzte Befehl lauten:

cat >> /home/ubuntu/Project/working/output.txt

Oder nur:

>> /home/ubuntu/Project/working/output.txt

Antwort2

Abgesehen von der Korrektur einiger kleiner Tippfehler in Ihrem Originalcode (Verwendung "$i"von anstelle von iund Umleitung der Ausgabe in die Ausgabedatei, anstatt zu versuchen, deren Inhalt auszugeben), können Sie Folgendes tun, wenn Sie nicht viele Tausend dieser list.txtDateien haben:

awk '/^bar[0-9]/ { print $1 }' /home/ubuntu/Project/working/library_*/Results/list.txt >output.txt

Dies wird verwendet, awkum die erste Spalte aller Zeilen zu extrahieren, die mit der Zeichenfolge beginnen, bargefolgt von einer Ziffer. Dies geschieht für alle Dateien, die dem Muster entsprechen /home/ubuntu/Project/working/library_*/Results/list.txt. Die extrahierten Daten werden umgeleitet an output.txt.

Die Schleife wird notwendig, wenn sich das Muster zum Globbing von Dateinamen /home/ubuntu/Project/working/library_*/Results/list.txtauf zu viele Namen ausdehnt:

for pathname in /home/ubuntu/Project/working/library_*/Results/list.txt; do
    awk '/^bar/ { print $1 }' "$pathname"
done >output.txt

Beachten Sie, dass es effizienter ist, die Ausgabe vondie Schleifeals von jedem einzelnen awkAnruf. Beachten Sie auch, dass awkdies die Aufgabe von leicht erledigt, grepdie gewünschten Leitungen zu erkennen, und dass dies catnicht erforderlich ist.

Wenn Sie die erste Spalte aller Zeilen außer der ersten benötigen (wie in Ihren Beispieldaten), können Sie die Bedingung im awkCode von /^bar[0-9]/in ändern FNR > 1.

verwandte Informationen