it-swarm.com.de

Wie kopiere ich den Inhalt jeder Datei in einer Liste in eine andere Datei?

Ich habe eine Liste von Dateinamen in einer Datei mit dem Namen list_of_files.txt.

Ich möchte den Inhalt jeder Datei in dieser Liste in eine andere Datei mit dem Namen all_compounds.sdf kopieren.

Wie soll ich das von der Kommandozeile aus machen?

15
Ramita Rajaa

Verwenden Sie keine einfache Befehlsersetzung, um Dateinamen abzurufen (dies kann leicht zu Leerzeichen und anderen Sonderzeichen führen). Verwenden Sie etwas wie xargs:

xargs -d '\n' -a list_of_files.txt cat > all_compounds.sdf

Oder eine while read -Schleife:

while IFS= read -r file; do cat "$file"; done < list_of_files.txt > all_compounds.sdf

Um die Befehlsersetzung sicher zu verwenden, setzen Sie IFS mindestens auf die neue Zeile und deaktivieren Sie das Globbing (Platzhaltererweiterung):

(set -f; IFS=$'\n'; cat $(cat list_of_files.txt) > all_compounds.sdf)

Die umgebenden Klammern () sollen dies in einer Subshell ausführen, damit Ihre aktuelle Shell von diesen Änderungen nicht betroffen ist.

20
muru

Schnell und dreckig unterwegs ...

cat $(cat list_of_files.txt) >> all_compounds.sdf

Bitte beachten Sie: Dies funktioniert nur, wenn sich die Dateinamen in Ihrer Liste sehr gut verhalten - Dinge werden schief gehen, wenn sie Leerzeichen, Zeilenumbrüche oder Zeichen enthalten, die haben eine besondere Bedeutung für die Shell - verwenden Sie diese Antwort stattdessen für zuverlässige Ergebnisse)

Anmerkungen

  • cat con cat aktiviert Dateien. Es druckt auch deren Inhalt.
  • Mit der Befehlssubstitution command2 $(command1) können Sie die Ausgabe von command1 (cat list...) an command2 (cat) übergeben, wodurch die Dateien verkettet werden.
  • Verwenden Sie dann die Umleitung >>, um die Ausgabe an eine Datei zu senden, anstatt an stdout zu drucken. Wenn Sie die Ausgabe sehen möchten, verwenden Sie stattdessen tee:

    cat $(cat list_of_files.txt) | tee -a all_compounds.sdf
    

(Ich habe >> anstelle von > und tee mit dem Schalter -a verwendet, falls Ihre Datei bereits vorhanden ist - dieser hängt an auf die Datei, anstatt sie zu überschreiben, falls sie bereits vorhanden ist)

14
Zanna

Während GNU awk ein Textverarbeitungsprogramm ist, können externe Shell-Befehle über den Aufruf system() ausgeführt werden. Das können wir so zu unserem Vorteil nutzen:

$ awk '{cmd=sprintf("cat \"%s\"",$0); system(cmd)}' file_list.txt                                                        

Die Idee hier ist einfach: Wir lesen die Datei Zeile für Zeile und erstellen aus jeder Zeile eine formatierte Zeichenfolge cat "File name.txt", die dann an system() übergeben wird.

Und hier ist es in Aktion:

$ ls
file1.txt  file2.txt  file3 with space.txt  file_list.txt


$ awk '{cmd=sprintf("cat \"%s\"",$0); system(cmd)}' file_list.txt                                                        
Hi, I'm file2
Hi, I'm file1
Hi, I'm file3

Wir haben dort also schon den größten Teil der Aufgabe erledigt - wir haben alle Dateien auf der Liste gedruckt. Der Rest ist einfach: Leiten Sie die endgültige Ausgabe mit dem Operator > in die Zusammenfassungsdatei um.

awk '{cmd=sprintf("cat \"%s\"",$0); system(cmd)}' file_list.txt > output.txt
4