Teilen Sie eine Datei zeilenweise auf und haben Sie die Kontrolle über die resultierende Dateierweiterung

28

Es gibt einen Standardbefehl zum Aufteilen von Dateien - Aufteilen.

Wenn ich zum Beispiel eine Wortdatei in mehrere Stücke von 10000 Zeilen aufteilen möchte, kann ich Folgendes verwenden:

split -dl 10000 words wrd

und es würde mehrere Dateien der Form wrd.01, wrd.02 und so weiter erzeugen.

Ich möchte jedoch eine bestimmte Erweiterung für diese Dateien haben, z. B. wtd.01.txt- oder wrd.02.txt-Dateien.

Gibt es eine Möglichkeit, dies zu tun?

Rogach
quelle

Antworten:

11

Nicht mit split, aber Sie können sie später leicht umbenennen, oder Sie können es tun in awk:

awk '{filename = "wrd." int((NR-1)/10000) ".txt"; print >> filename}' inputfile
Kevin
quelle
Sieht gut aus - funktioniert aber nicht. Beschwert sich in Ihrem Formular über "Ausdruck für >> -Umleitung hat Null-Zeichenfolgewert" und gibt Dateien der Form wrd. {Dateinummer}. {Zeilennummer} aus, wenn "Datei" in "Dateiname" geändert wird. .txt (ziemlich viele von ihnen :)
Rogach
@ Rogach Sorry, ich hatte es nicht getestet, also habe ich vergessen, dass awk keine Ganzzahldivision durchführt. Ich habe diesen getestet.
Kevin
49

Dies war damals noch nicht verfügbar, aber mit neueren Versionen ( ≥ 8.16) gnu splitkann man den --additional-suffixSchalter verwenden, um die resultierende Erweiterung zu steuern. Von man split:

--additional-suffix=SUFFIX
              append an additional SUFFIX to file names.

Wenn Sie diese Option verwenden:

split -dl 10000 --additional-suffix=.txt words wrd

die resultierenden Stücke enden automatisch in .txt:

wrd00.txt
wrd01.txt
.........
don_crissti
quelle
3
Ich arbeite nicht am Mac
ericgu 10.02.15
2
Ich liebe deinen Sarkasmus. Ich bin ein Unix n00b aus der Apple-Welt. Ich benutze OS X Yosemite und wollte einfach nicht, dass andere abstürzen und brennen, wie ich es tat. Ich habe in den Dokumenten getestet und überprüft, und wir haben diesen Parameter nicht. Ich könnte etwas verpasst haben. developer.apple.com/library/mac/documentation/Darwin/Reference/…
ericgu
5
@swiftshokunin - meine Antwort bezieht sich auf einen gnu splitTeil von gnu coreutils. Es ist auch unter OSX verfügbar, wenn Sie coreutilsüber installieren. homebrewBeachten Sie jedoch, dass die gnuDienstprogramme unter OSX standardmäßig einen gvorangestellten Namen haben (z. B. gstatanstelle von stat), sodass Sie ihn wie in gsplitder Anleitung hier beschrieben aufrufen (oder den PFAD ändern , wenn Sie möchten) um es wie splitüber das OSX zu benutzen split). HTH.
don_crissti
1
Gute Antwort. Verwenden Sie unter OS X, gsplitdamit die numerischen Suffixe (-d) funktionieren.
Brent Faust
1
wow, ich hatte keine Ahnung, dass es gsplit gibt - es ist wahrscheinlich von Coreutils oben erwähnt und es hat --additional-Suffix. Vielen Dank an alle, die diese Lösung kommentiert haben :)
Łukasz Rysiak
13

Solche Aufgaben erledigen Sie am besten mit der Shell. Verwenden Sie split und schreiben Sie eine einfache Schleife, um die Dateien umzubenennen. Z.B

for file in wrd.*
do
    mv "$file" "$file.txt"
done

Benennen Sie Ihre Dateien wrd.01, wrd.02 usw. um, damit sie alle die Erweiterung .txt haben.

Kyle Jones
quelle
Das liegt auf der Hand, würde aber die Prägnanz von Bash-Skripten sprengen.
Rogach
1
Die Unix-Philosophie besteht darin, Ihnen eine Reihe einfacher Werkzeuge zur Verfügung zu stellen, die Sie dann kombinieren, um einen Job zu erledigen. Die "Prägnanz des Bash-Skripts" war in Ihrer Frage keine festgelegte Voraussetzung.
Kyle Jones
7
PS: Die split+mvCombo ist mehr als 6-mal schneller als awk(ca. 3s vs 18s ) für eine 10-Millionen-Zeilen-Eingabedatei (75 MB) ... der Text in jeder Zeile hatte eine eigene Zeilennummer ... Danke für die erneute Angabe die "offensichtliche" :)
Peter.O
3
PPS: Ich habe das gerade ein bisschen genauer untersucht. Der Geschwindigkeitsunterschied hängt von der Anzahl der erstellten Dateien und der Anzahl der Formatierungs- und Rechenoperationen ab, die awk für jede Zeile unabhängig von der Anzahl der Ausgabedateien ausführt ... Verwenden derselben Eingabedatei wie im obigen Beispiel: Wenn vorhanden 100-mal weniger Dateien, split + mvist 75- mal schneller als awk: Wenn 100-mal mehr Dateien vorhanden sind, split + mvist 1,5- mal schneller als awk. Für mich split + mvgewinnt diese Methode zweifellos. Es ist als consice (wohl mehr) und ist schneller als awk.
Peter.O
1
Wenn Sie sich Sorgen machen, dass es 5 Zeilen lang ist, versuchen Sie es stattdessen: for file in wrd.*; do mv "$file" "$file.txt"; done:)
Tony