
Ich habe eine Reihe von Verzeichnissen, alle im list.txt
gleichen 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.txt
mithilfe 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 Name
Werte 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 i
anstelle dieser Verwendung $i
im 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 i
und Umleitung der Ausgabe in die Ausgabedatei, anstatt zu versuchen, deren Inhalt auszugeben), können Sie Folgendes tun, wenn Sie nicht viele Tausend dieser list.txt
Dateien haben:
awk '/^bar[0-9]/ { print $1 }' /home/ubuntu/Project/working/library_*/Results/list.txt >output.txt
Dies wird verwendet, awk
um die erste Spalte aller Zeilen zu extrahieren, die mit der Zeichenfolge beginnen, bar
gefolgt 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.txt
auf 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 awk
Anruf. Beachten Sie auch, dass awk
dies die Aufgabe von leicht erledigt, grep
die gewünschten Leitungen zu erkennen, und dass dies cat
nicht 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 awk
Code von /^bar[0-9]/
in ändern FNR > 1
.