Wie kann ich eine Datei über die Befehlszeile kürzen?

9

Ich habe eine 150-GB-XML-Datei, die ich auf ca. 1 GB kürzen (dh abschneiden) möchte - kann ich einen einfachen (bash oder ähnlichen) Befehl verwenden oder muss ich die programmatische Route wählen (in vi oder emacs bearbeiten)? ist ein Albtraum auch auf großen Eisensystemen)?

(Ich bin nicht besonders besorgt über den Verlust von Informationen, ich möchte eine kürzere Datei, damit ich ein Stück Software darauf testen und nicht viele Stunden auf die Antwort warten kann. Mit einer kürzeren Datei kann ich das tun.)

adrianmcmenamin
quelle
1
Wollen Sie die Datei abschneiden oder möchten Sie Informationen aus der gesamten Datei entfernen?
AFH
1
Fand dies auf SO; stackoverflow.com/a/15934078/2800918 .
CAB
2
Da dies eine XML-Datei ist, von der ich annehme, dass sie eine Sequenz mit einer großen Anzahl von Elementen enthält, können Sie auch eine XML-Transformationssprache wie XQuery verwenden, um eine bestimmte Anzahl dieser Elemente herauszufiltern. Dies hätte den Vorteil, dass gültiges XML ausgegeben wird ( Beispiel )
Aaron
4
Muss die Datei zum Abschluss noch gültiges XML sein?
Joe
1
nein, ich habe es gerade ausgebessert
adrianmcmenamin

Antworten:

15

Angenommen, Sie möchten die ersten 1 GB der 150 GB-Datei abschneiden und extrahieren:

Mit head:

head -c 1G infile > outfile

Beachten Sie, dass das GSuffix ersetzt werden kann GB, um 1000 anstelle von 1024 auszurichten.

Oder mit dd:

dd if=infile of=outfile bs=1M count=1024

Oder wie in Wumpus Q. Wumbleys Antwort, ddkann an Ort und Stelle abgeschnitten werden.

multithr3at3d
quelle
5
Das wird wahrscheinlich nicht zu einer lesbaren XML-Datei führen, wenn Sie fertig sind.
Joe
3
@Joe - OP hat keine lesbare Datei angefordert (und sie sagten auch nicht, dass sie nicht lesbar sein könnte). Sie sagten, dass ihnen der Verlust von Informationen egal sei. Ich würde eine neue Frage von OP erwarten, wie man besagte Akte regelt.
KevinDTimm
3
Ich kenne genug XML, um das Problem zu beheben. Ich habe die DTD für das Format geschrieben.
Adrianmcmenamin
37

Verwenden Sie den folgenden truncateBefehl , um eine Datei auf 1 GB zu kürzen :

truncate -s 1G file.xml

Das Ergebnis der Kürzung wird wahrscheinlich keine gültige XML-Datei sein, aber ich habe festgestellt, dass Sie das verstehen.

Dokumentation für die GNU-Version von truncateist hier und Dokumentation für die BSD-Version ist hier

John1024
quelle
14

Wo immer möglich, würde ich den truncateBefehl wie in John1024s Antwort verwenden. Es ist jedoch kein Standard-Unix-Befehl, sodass Sie möglicherweise eines Tages nicht in der Lage sind, ihn zu verwenden. In diesem Fall ddkann auch eine direkte Kürzung durchgeführt werden.

ddStandardmäßig wird die Ausgabedatei an der Stelle abgeschnitten, an der der Kopiervorgang endet. Geben Sie ihr also eine Eingabedatei mit der Länge 0 und teilen Sie ihr mit, dass sie an der gewünschten Stelle mit dem Schreiben beginnen soll:

dd if=/dev/null of=filename bs=1048576 seek=1024

(Dies ist nicht dasselbe wie das Kopieren und Abschneiden ddin der Antwort von multithr3at3d.)

Beachten Sie, dass ich 1048576 und 1024 verwendet habe, da 1048576 * 1024 die gewünschte Größe ist. Ich vermied bs = 1m , weil dies eine „Portabilität“ Antwort ist, und klassische ddkennt nur Suffixe k, bund w.


quelle
2
Für die allgemeine Lösung sollten Sie wahrscheinlich beachten, dass die mit der bsZahl multiplizierte seekZahl die Anzahl der zu speichernden Bytes ist. Zwei beliebige Zahlen, die diese Bedingung erfüllen, sollten funktionieren. zB bs=1073741824 seek=1oder bs=1 seek=1073741824. Oder, da die bsStandardeinstellung 512 ist, seek=2097152sollte auch alleine funktionieren. Und Sie können Notation wie verwenden 1M, 1K, 1Gund 2M.
G-Man
1

Ich bin nicht ganz sicher, was Sie fragen. Möchten Sie nur die anderen 149 GB loswerden oder versuchen Sie, 150 GB auf 1 GB zu komprimieren? Unabhängig davon kann dies eine nützliche Methode sein, um dies zu erreichen.

Der splitBefehl kann jede Datei in mehrere Teile aufteilen. Siehe Mann gespalten . Mit der -bOption können Sie die Größe der Datei-Chunks festlegen, in die Sie sie aufteilen möchten . Zum Beispiel:

$ split -b 1GB myfile.xml

Ohne weitere Optionen sollten dabei mehrere Dateien im aktuellen Verzeichnis erstellt werden, die mit dem Buchstaben beginnen x. Wenn Sie die Namen der aufgeteilten Dateien anpassen möchten, lesen Sie die Manpage.

Um die Datei wieder zusammenzusetzen, verwenden Sie einfach cat * > re-assembled.xml.

Beispiel:

[kent_x86.py@c7 split-test]$ ls -l opendocman*
-rw-rw-r--.  1 kent_x86.py kent_x86.py 2082602 Mar 31  2017 opendocman-1.3.5.tar.gz

[kent_x86.py@c7 split-test]$ split -b 100K opendocman-1.3.5.tar.gz 
[kent_x86.py@c7 split-test]$ ls
opendocman-1.3.5.tar.gz  xaa  xab  xac  xad  xae  xaf  xag  xah  xai  xaj  xak  xal  xam  xan  xao  xap  xaq  xar  xas  xat  xau
[kent_x86.py@c7 split-test]$ ll
total 4072
-rw-rw-r--. 1 kent_x86.py kent_x86.py 2082602 Jan  5 11:06 opendocman-1.3.5.tar.gz
-rw-rw-r--. 1 kent_x86.py kent_x86.py  102400 Jan  5 11:06 xaa
-rw-rw-r--. 1 kent_x86.py kent_x86.py  102400 Jan  5 11:06 xab
-rw-rw-r--. 1 kent_x86.py kent_x86.py  102400 Jan  5 11:06 xac
-rw-rw-r--. 1 kent_x86.py kent_x86.py  102400 Jan  5 11:06 xad
-rw-rw-r--. 1 kent_x86.py kent_x86.py  102400 Jan  5 11:06 xae
-rw-rw-r--. 1 kent_x86.py kent_x86.py  102400 Jan  5 11:06 xaf
-rw-rw-r--. 1 kent_x86.py kent_x86.py  102400 Jan  5 11:06 xag
-rw-rw-r--. 1 kent_x86.py kent_x86.py  102400 Jan  5 11:06 xah
-rw-rw-r--. 1 kent_x86.py kent_x86.py  102400 Jan  5 11:06 xai
-rw-rw-r--. 1 kent_x86.py kent_x86.py  102400 Jan  5 11:06 xaj
-rw-rw-r--. 1 kent_x86.py kent_x86.py  102400 Jan  5 11:06 xak
-rw-rw-r--. 1 kent_x86.py kent_x86.py  102400 Jan  5 11:06 xal
-rw-rw-r--. 1 kent_x86.py kent_x86.py  102400 Jan  5 11:06 xam
-rw-rw-r--. 1 kent_x86.py kent_x86.py  102400 Jan  5 11:06 xan
-rw-rw-r--. 1 kent_x86.py kent_x86.py  102400 Jan  5 11:06 xao
-rw-rw-r--. 1 kent_x86.py kent_x86.py  102400 Jan  5 11:06 xap
-rw-rw-r--. 1 kent_x86.py kent_x86.py  102400 Jan  5 11:06 xaq
-rw-rw-r--. 1 kent_x86.py kent_x86.py  102400 Jan  5 11:06 xar
-rw-rw-r--. 1 kent_x86.py kent_x86.py  102400 Jan  5 11:06 xas
-rw-rw-r--. 1 kent_x86.py kent_x86.py  102400 Jan  5 11:06 xat
-rw-rw-r--. 1 kent_x86.py kent_x86.py   34602 Jan  5 11:06 xau
[kent_x86.py@c7 split-test]$ cat xa* > opendoc-reassembled.tar.gz
[kent_x86.py@c7 split-test]$ ls -l opendoc-reassembled*
-rw-rw-r--. 1 kent_x86.py kent_x86.py 2082602 Jan  5 11:07 opendoc-reassembled.tar.gz
Kentgrav
quelle
0

Sie können den splitBefehl verwenden.

split -C 1G <filename>

Weitere Informationen finden Sie in dieser Stackoverflow-Antwort

ventsyv
quelle
0

Am Ende habe ich nur sedeine beliebige Anzahl von Zeilen extrahiert:

sed -n 1,1000000p infile.xml>outfile.xml
adrianmcmenamin
quelle
1
Abgesehen davon, ob hierdurch die Frage beantwortet wird oder nicht, wird hierdurch die gesamte Datei gescannt, was meiner Meinung nach eine wesentlich effizientere Verwendung ermöglicht sed 1000000q(und visuell etwas kompakter).
B Schicht