Como cortar um arquivo para um determinado tamanho no Linux?

16

Eu quero reduzir o tamanho de um arquivo pela força bruta, ou seja, não me importo com o resto, só quero cortar o arquivo, digamos, pela metade, e descartar o resto.

A primeira coisa que vem à mente é o truncado do Perl. Estou seguindo o exemplo nessa página e fiz exatamente a mesma coisa:

seq 9 > test.txt
ls -l test.txt
perl -we 'open( FILE, "< ./test.txt" ) && truncate( FILE, 8 ) && close(FILE);'

Mas o arquivo ainda tem o mesmo tamanho:

$ ls -lgG test.txt
-rw-rw---- 1 18 2013-08-08 09:49 test.txt

Como posso fazer isso funcionar?

    
por xpt 08.08.2013 / 16:27

5 respostas

55

Você pode querer usar o comando truncate :

truncate --size=1G test.txt

SIZE pode ser especificado como bytes, KB, K, MB, M, etc. Suponho que você pode calcular o tamanho desejado manualmente; se não, você provavelmente poderia usar o comando stat para obter informações sobre o tamanho atual do arquivo.

    
por 08.08.2013 / 16:32
21
perl -we 'open( FILE, "< ./test.txt" ) && truncate( FILE, 8 ) && close(FILE);'

abre o arquivo para leitura. No entanto, para truncar o arquivo, é necessário modificá-lo, portanto, um identificador de arquivo somente leitura não funcionará. Você precisa usar o modo "modificar" ( "+>" ).

Como uma questão secundária, sempre me surpreende quando as pessoas deixam as chamadas do sistema falharem silenciosamente e depois perguntam o que deu errado. Uma parte essencial de diagnosticar um problema é examinar a mensagem de erro produzida; mesmo que você não entenda, isso torna a vida muito mais fácil para aqueles que você pede ajuda.

O seguinte seria um pouco mais útil:

perl -we 'open(FILE, "<", "./test.txt") or die "open: $!";
          truncate(FILE, 8) or die "truncate: $!";
          close(FILE);'

apesar de admitir que só teria relatado "argumento inválido". Ainda assim, essa é uma informação útil e pode ter levado você à conclusão de que o modo aberto estava errado (como aconteceu comigo).

    
por 08.08.2013 / 18:58
2

Você pode usar a cauda para cortar até 100000 bytes

tail -c 100000 file > file2

as saídas -c começando com o byte 100000 deste arquivo neste caso

mv file2 file

substitui o arquivo original pelo arquivo que você acabou de gerar

    
por 08.09.2017 / 12:24
1

A resposta acima citando truncado é legal. dd também fará o trabalho:

dd if=test.txt of=test2.txt bs=1 count=8
mv test2.txt test.txt
    
por 30.04.2018 / 15:58
0

existe uma maneira completamente diferente de fazer isso, com o bash, usando o programa ed. O script a seguir manterá apenas as últimas 5000 linhas de todos os arquivos no diretório especificado. isso pode ser facilmente modificado para passar por vários diretórios, alterar o número de linhas, etc.

#!/bin/bash

LOGDIR=/opt/log
SAVELINES=5000

dirs="$LOGDIR"
for dir in $dirs ; do
    files=${dir}/*
    for f in $files ; do
        echo -e "1,-${SAVELINES}d\nwq" | ed $f 1>/dev/null 2>&1
    done
done
    
por 23.05.2017 / 23:44