Comment raccourcir un fichier depuis la ligne de commande?

9

J'ai un fichier xml de 150 Go que je voudrais raccourcir (c'est-à-dire tronquer) à environ 1 Go - y a-t-il une commande simple (bash ou similaire) que je peux utiliser, ou dois-je suivre la route programmatique (le modifier dans vi ou emacs est un cauchemar même sur les gros systèmes de fer)?

(Je ne suis pas particulièrement préoccupé par la perte d'informations, je veux un fichier plus court afin que je puisse tester un logiciel à ce sujet et ne pas attendre plusieurs heures pour la réponse, un fichier plus court me permettra de le faire.)

adrianmcmenamin
la source
1
Voulez-vous dire que vous voulez tronquer le fichier, ou voulez-vous supprimer des informations de tout le fichier?
AFH
1
J'ai trouvé ça sur SO; stackoverflow.com/a/15934078/2800918 .
CAB
2
Comme il s'agit d'un fichier XML, qui, je suppose, contient une séquence avec un grand nombre d'éléments, vous pouvez également utiliser un langage de transformation XML tel que XQuery pour filtrer un certain nombre de ces éléments, ce qui aurait l'avantage de générer du XML valide ( Exemple )
Aaron
4
Le fichier doit-il toujours être du XML valide une fois terminé?
Joe
1
non, je l'ai juste corrigé donc c'était
adrianmcmenamin

Réponses:

15

En supposant que vous souhaitiez tronquer et extraire le premier 1 Go du fichier de 150 Go:

Avec head:

head -c 1G infile > outfile

Notez que le Gsuffixe peut être remplacé par GBpour s'aligner sur 1000 au lieu de 1024.

Ou avec dd:

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

Ou comme dans Wumpus Q. La réponse de Wumbley, ddpeut tronquer en place.

multithr3at3d
la source
5
Cela ne donnera probablement pas lieu à un fichier XML lisible une fois terminé.
Joe
3
@Joe - OP n'a pas demandé un fichier lisible (ni dit qu'il pourrait être illisible). Ils ont dit ne pas se soucier de la perte d'informations. Je m'attendrais à une nouvelle question de OP sur la façon de réparer ledit fichier.
KevinDTimm
3
Je connais suffisamment de xml pour le corriger, j'ai écrit la DTD pour le format!
adrianmcmenamin
37

Pour tronquer un fichier à 1 gigaoctet, utilisez la truncatecommande:

truncate -s 1G file.xml

Le résultat de la troncature ne sera probablement pas un fichier XML valide, mais je suppose que vous comprenez cela.

La documentation pour la version GNU truncateest ici et la documentation pour la version BSD est ici

John1024
la source
14

Dans la mesure du possible, j'utiliserais la truncatecommande comme dans la réponse de John1024. Ce n'est pas une commande Unix standard, donc vous pourriez un jour vous retrouver incapable de l'utiliser. Dans ce cas, ddpeut également effectuer une troncature sur place.

ddLe comportement par défaut est de tronquer le fichier de sortie au point où la copie se termine, il vous suffit donc de lui donner un fichier d'entrée de longueur 0 et de lui dire de commencer à écrire au point de troncature souhaité:

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

(Ce n'est pas la même chose que la copie et la troncature dddans la réponse de multithr3at3d.)

Notez que j'ai utilisé 1048576 et 1024 car 1048576 * 1024 est la taille souhaitée. J'évitais bs = 1m parce que c'est une réponse « portabilité », et classique ddne connaît que suffixes k, bet w.


la source
2
Pour la solution générale, vous devez probablement noter que le bsnombre multiplié par le seeknombre est le nombre d'octets à conserver. Deux nombres qui satisfont à cette contrainte devraient fonctionner; par exemple, bs=1073741824 seek=1ou bs=1 seek=1073741824. Ou, comme la valeur par bsdéfaut est 512, seek=2097152seul devrait également fonctionner. Et vous pouvez utiliser la notation comme 1M, 1K, 1Get 2M.
G-Man dit `` Réintègre Monica '' le
1

Je ne suis pas tout à fait sûr de ce que vous demandez. Voulez-vous simplement vous débarrasser des 149 Go restants ou essayez-vous de compresser 150 Go en 1 Go? Quoi qu'il en soit, cela peut être une méthode utile pour y parvenir.

La splitcommande peut diviser n'importe quel fichier en plusieurs morceaux. Voir l' homme fendu . Vous pouvez spécifier la taille des morceaux de fichier que vous souhaitez diviser en avec l' -boption. Par exemple:

$ split -b 1 Go monfichier.xml

Sans aucune autre option, cela devrait créer plusieurs fichiers dans le répertoire courant en commençant par la lettre x. Si vous souhaitez ajuster les noms des fichiers divisés, reportez-vous à la page de manuel.

Pour réassembler le fichier, utilisez simplement cat * > re-assembled.xml.

Exemple:

[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
la source
0

Au final, je viens sedd'extraire un nombre arbitraire de lignes:

sed -n 1,1000000p infile.xml>outfile.xml
adrianmcmenamin
la source
1
Mis à part si cela répond à la question ou non, cela analysera l'intégralité du fichier, je pense, donc il est beaucoup plus efficace à utiliser sed 1000000q(et un peu plus compact, visuellement parlant).
B Layer