2012-05-24 10 views
10

Ich versuche mit bash, den Inhalt einer Liste von Dateien (mehr als 1K) in eine große Datei zusammenzuführen.shell - cat - Zusammenführen von Dateien in eine große Datei

Ich habe den folgenden Befehl cat versucht:

cat * >> bigfile.txt 

jedoch, was dieser Befehl tut, ist alles zusammenführen, enthalten auch die Dinge bereits verschmolzen.

z.B. file1.txt

content1 

file2.txt

content2 

file3.txt

content3 

file4.txt

content4 

bigfile.txt

content1 
content2 
content3 
content2 
content3 
content4 
content2 

aber ich würde nur

content1 
content2 
content3 
content4 

in der TXT-Datei

Der andere Weg cat file1.txt file2.txt ... und so weiter sein möge ... aber ich kann es nicht als 1k-Dateien für mehr!

Vielen Dank für Ihre Unterstützung!

Antwort

18

Das Problem ist, dass Sie bigfile in das gleiche Verzeichnis, wodurch es Teil von *. So etwas wie

cat dir/* > bigfile 

sollte gerade arbeiten, wie Sie es wollen, mit Ihrem fileN.txt Dateien befindet sich in dir/

+1

... oder 'cat *>/tmp/bigfile; mv/tmp/bigfile .'. – tripleee

+0

Ich denke, fabioln enthält absichtlich "bigfile.txt" in der Eingabe; Er möchte die Datei aus den verschiedenen 'file * .txt' Dateien hinzufügen, aber Duplikate gleichzeitig entfernen. – chepner

+0

Danke Jungs. Ja, das war das Problem! Ich habe die Bigfile in das selbe Verzeichnis gelegt ... also habe ich den Befehl benutzt, den du mir gegeben hast (cat dir/*> bigfile)! Nur eine andere Frage: Warum hast du nur> statt von> gesetzt? Vielen Dank! – fabioln79

-3

Versuchen:

cat `ls -1 *` >> bigfile.txt 

Ich habe keine Unix-Maschine praktisch im Moment um es zuerst für dich zu testen.

+2

-1 Dies löst nichts und bringt einige neue Probleme mit sich. Verwenden Sie 'ls' nicht, wenn der Platzhalter bereits auf die gewünschten Dateien expandiert! Verwenden Sie keine unbenannten Dateinamen (die Ausgabe von den Backticks), da sie bricht, wenn Dateinamen Whitespace enthalten. – tripleee

+0

Ich dachte eigentlich an eine Schleife, als ich das schrieb, aber es kam nicht richtig aus meinem Kopf. Ich mag Bartons Antwort trotzdem besser. – JerseyMike

4

Wenn Sie Ihre Frage erneut lesen, scheint es, dass Sie Daten an bigfile.txt, aber anhängen möchten, ohne Duplikate hinzuzufügen. Sie werden alles durch sort -u passieren müssen, um Duplikate zu filtern:

sort -u * -o bigfile.txt 

Die -o Option zu sortieren können Sie sicher, um den Inhalt von bigfile.txt im Eingabe enthalten zu sortieren, bevor die Datei mit dem Ausgang überschrieben wird.

EDIT: Unter der Annahme, bigfile.txt sortiert ist, können Sie einen zweistufigen Prozess versuchen:

sort -u file*.txt | sort -um - bigfile.txt -o bigfile.txt 

Zuerst haben wir die Eingabedateien sortieren, Duplikate zu entfernen.Wir leiten diese Ausgabe an einen anderen sort -u Prozess weiter, wobei dieser die -m Option verwendet, die sort anweist, zwei zuvor sortierte Dateien zusammenzuführen. Die beiden Dateien, die wir zusammenführen werden, sind (Standardeingabe, der Stream kommt von der ersten sort) und bigfile.txt selbst. Wir verwenden wieder die -o Option, um es uns zu ermöglichen, die Ausgabe zurück nach bigfile.txt zu schreiben, nachdem wir es als Eingabe gelesen haben.

+0

Ich habe die Antwort so geändert, dass neue Daten in "bigfile.txt" so zusammengeführt werden können, dass sie sortiert bleibt und keine Duplikate eingefügt werden. Ich denke, das ist das Beste, was Sie tun können, ohne in ein strukturierteres Format (wie eine Datenbank) zu wechseln. – chepner

4

Sie können die Ausgabedatei im gleichen Verzeichnis halten, müssen Sie nur noch als * ein bisschen anspruchsvoller sein:

shopt -s extglob 
cat !(bigfile.txt) > bigfile.txt 
+0

Danke. Ich habe eine Frage zu diesem Befehl: das Verzeichnis, das die Datei enthält, hat eine Größe von 557GB, aber das erstellte Bigfile hat eine Größe von 495. Ich weiß nicht, wie ich das erklären soll. Ich mache etwas falsch? Vielen Dank! – fabioln79

+0

@ fabioll79 Mit der Menge der zur Verfügung gestellten Informationen, könnte dies auf den tatsächlich verwendeten Speicherplatz im Vergleich zur Blockgröße zurückzuführen sein (Lesen Sie mehr dazu) – user66001

2

Der andere Weg Katze file1.txt file2.txt wäre .. und so weiter ... aber ich kann es nicht für mehr als 1k Dateien machen!

Dies ist, was xargs ist für:

find . -maxdepth 1 -type f -name "file*.txt" -print0 | xargs -0 cat > bigfile.txt 
+0

führt xargs den Befehl für * jedes * Argument aus? Wenn ja, sollten Sie ">>" anstelle von ">" verwenden? Ich denke, wenn es fertig ist, wird bigfile.txt nur den Inhalt der zuletzt übergebenen Datei enthalten. – JerseyMike

+1

xargs führt den Befehl einmal für alle Argumente aus, Sie müssen nicht ">>" verwenden. –

+0

Vielen Dank für die Klarstellung. Die Manpage war mir nicht sehr klar. – JerseyMike

1

Dies ist eine alte Frage, aber ich werde noch einen weiteren Ansatz mit xargs

  1. Liste die Dateien, die Sie geben

    verketten

    ls | grep [pattern]> Liste der Dateien

  2. Überprüfen Sie Ihre Dateien in der richtigen Reihenfolge sind mit vi oder cat. Wenn Sie ein Suffix (1, 2, 3, ..., N) sollte dies kein Problem sein

  3. die letzte Datei erstellen

    Katze Liste der Dateien | xargs cat >> [final Datei]

  4. Entfernen Sie die Liste der Dateien

    rm -f Dateiliste

Hoffnung hilft dieses jemand

Verwandte Themen