Come accorciare un file dalla riga di comando?


9

Ho un file xml da 150 GB che vorrei accorciare (cioè troncare) a circa 1 GB: esiste un comando semplice (bash o simile) che posso usare o devo seguire il percorso programmatico (modificandolo in vi o emacs è un incubo anche su grandi sistemi di ferro)?

(Non sono particolarmente preoccupato per la perdita di informazioni, voglio un file più breve in modo da poter testare un software su questo e non aspettare molte ore per la risposta, un file più breve mi permetterà di farlo.)


1
Vuoi dire che vuoi troncare il file o vuoi rimuovere informazioni da tutto il file?
AFH,

1
Trovato questo su SO; stackoverflow.com/a/15934078/2800918 .
CAB

2
Poiché si tratta di un file XML, che presumo contenga una sequenza con un gran numero di elementi, è possibile utilizzare anche un linguaggio di trasformazione XML come XQuery per filtrare un certo numero di questi elementi, il che avrebbe il vantaggio di produrre un XML valido ( Esempio )
Aaron,

4
Al termine, il file deve essere ancora XML valido?
Joe,

1
no, l'ho appena riparato così com'era
adrianmcmenamin il

Risposte:


15

Supponendo di voler troncare ed estrarre i primi 1 GB del file da 150 GB:

Con head:

head -c 1G infile > outfile

Si noti che il Gsuffisso può essere sostituito con GBper allineare a 1000 anziché a 1024.

O con dd:

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

O come nella risposta di Wumpus Q. Wumbley, ddpuò troncarsi sul posto.


5
Ciò non comporterà probabilmente un file XML leggibile al termine.
Joe,

3
@Joe - OP non ha richiesto un file leggibile (né hanno detto che potrebbe essere illeggibile). Hanno detto che non gli importava della perdita di informazioni. Mi aspetto una nuova domanda da OP su come riparare detto file.
KevinDTimm,

3
Conosco abbastanza xml per risolverlo, ho scritto il DTD per il formato!
adrianmcmenamin,

37

Per troncare un file a 1 gigabyte, utilizzare il truncatecomando:

truncate -s 1G file.xml

Il risultato del troncamento probabilmente non sarà un file XML valido ma ho capito che lo capisci.

La documentazione per la versione GNU di truncateè qui e la documentazione per la versione BSD è qui


14

Ove possibile, truncateuserei il comando come nella risposta di John1024. Tuttavia, non è un comando unix standard, quindi un giorno potresti trovarti incapace di usarlo. In tal caso, ddpuò eseguire anche un troncamento sul posto.

ddIl comportamento predefinito è quello di troncare il file di output nel punto in cui termina la copia, quindi basta dargli un file di input di lunghezza 0 e dirgli di iniziare a scrivere nel punto di troncamento desiderato:

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

(Questo non è lo stesso del copia-e-tronca ddnella risposta di multithr3at3d.)

Si noti che ho usato 1048576 e 1024 perché 1048576 * 1024 è la dimensione desiderata. Ho evitato bs = 1m, perché questa è una risposta "portabilità", e classico ddconosce solo suffissi k, be w.


2
Per la soluzione generale, dovresti probabilmente notare che il bsnumero moltiplicato per il seeknumero è il numero di byte da conservare. Ogni due numeri che soddisfano tale vincolo dovrebbe funzionare; ad es . bs=1073741824 seek=1oppure bs=1 seek=1073741824. Oppure, poiché i bsvalori predefiniti sono 512, anche seek=2097152solo dovrebbe funzionare. Ed è possibile utilizzare la notazione come 1M, 1K, 1Ge 2M.
G-Man dice "Ripristina Monica" il

1

Non sono del tutto sicuro di ciò che stai chiedendo. Vuoi solo sbarazzarti degli altri 149 GB o stai cercando di comprimere 150 GB in 1 GB? Indipendentemente da ciò, questo può essere un metodo utile per raggiungere questo obiettivo.

Il splitcomando può dividere qualsiasi file in più pezzi. Vedi uomo diviso . È possibile specificare la dimensione dei blocchi di file in cui si desidera dividerlo con l' -bopzione. Per esempio:

$ split -b 1GB myfile.xml

Senza altre opzioni, ciò dovrebbe creare diversi file nella directory corrente a partire dalla lettera x. Se si desidera regolare i nomi dei file divisi, consultare la pagina man.

Per riassemblare il file basta usare cat * > re-assembled.xml.

Esempio:

[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


0

Alla fine ho usato solo sedper estrarre un numero arbitrario di righe:

sed -n 1,1000000p infile.xml>outfile.xml

1
Mettendo da parte se questo risponde alla domanda o meno, questo scansionerà l'intero file, credo, quindi è molto più efficiente da usare sed 1000000q(e un po 'più compatto, visivamente parlando).
B Layer
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.