Como posso encurtar um arquivo a partir da linha de comando?

9

Eu tenho um arquivo xml de 150GB que eu gostaria de encurtar (ou seja, truncar) para cerca de 1GB - existe um comando simples (bash ou similar) que eu possa usar, ou eu tenho que seguir a rota programática vi ou emacs é um pesadelo mesmo em grandes sistemas de ferro)?

(Eu não estou particularmente preocupado com a perda de informações, eu quero um arquivo mais curto para que eu possa testar um software sobre isso e não esperar muitas horas pela resposta, um arquivo mais curto me permitirá fazer isso.)

    
por adrianmcmenamin 05.01.2018 / 16:49

6 respostas

15

Supondo que você deseja truncar e extrair os primeiros 1 GB do arquivo de 150 GB:

com head :

head -c 1G infile > outfile

Observe que o sufixo G pode ser substituído por GB para alinhar a 1000 em vez de 1024.

Ou com dd :

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

Ou como na resposta da Wumpus Q. Wumbley, dd pode truncar no lugar.

    
por 05.01.2018 / 17:10
37

Para truncar um arquivo para 1 gigabyte, use o comando truncate :

truncate -s 1G file.xml

O resultado do truncamento provavelmente não será um arquivo XML válido, mas percebo que você entende isso.

A documentação para a versão GNU de truncate é aqui e documentação para a versão do BSD é aqui

    
por 05.01.2018 / 17:25
14

Sempre que possível, eu usaria o comando truncate como na resposta de John1024. Não é um comando unix padrão, embora você possa, algum dia, não conseguir usá-lo. Nesse caso, dd também pode fazer um truncamento no local.

O comportamento padrão do

dd é truncar o arquivo de saída no ponto em que a cópia termina, para que você apenas forneça um arquivo de entrada de comprimento igual a 0 e peça para ele começar a escrever no ponto de truncamento desejado:

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

(Isto não é o mesmo que o copiar e truncar dd na resposta do multithr3at3d.)

Note que usei 1048576 e 1024 porque 1048576 * 1024 é o tamanho desejado. Eu evitei bs = 1m porque essa é uma resposta de "portabilidade", e o clássico dd apenas conhece os sufixos k , b e w .

    
por 05.01.2018 / 18:48
1

Não sei bem o que você está perguntando. Você só quer se livrar dos outros 149GB ou está tentando comprimir 150GB em 1 GB? Independentemente disso, este pode ser um método útil para conseguir isso.

O comando split pode dividir qualquer arquivo em várias partes. Veja divisão do homem . Você pode especificar o tamanho dos fragmentos de arquivos que você deseja dividir com a opção -b . Por exemplo:

$ split -b 1GB myfile.xml

Sem nenhuma outra opção, isso deve criar vários arquivos no diretório atual, começando com a letra x . Se você quiser ajustar os nomes dos arquivos divididos, consulte a man page.

Para montar novamente o arquivo, use apenas cat * > re-assembled.xml .

Exemplo:

[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
    
por 05.01.2018 / 17:13
0

Você pode usar o comando split .

split -C 1G <filename>

Para mais detalhes, veja este

    
por 05.01.2018 / 17:11
0

No final, usei apenas sed para extrair um número arbitrário de linhas:

sed -n 1,1000000p infile.xml>outfile.xml
    
por 05.01.2018 / 17:45