Как вырезать файл до заданного размера под Linux?

19

Я хочу уменьшить размер файла с помощью грубой силы, то есть мне все равно, я просто хочу разрезать файл, скажем, наполовину и отказаться от остальных.

Первое, что приходит на ум - это усечение Perl . Я следую примеру на этой странице и сделал то же самое:

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

Но файл все еще имеет тот же размер:

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

Как я могу сделать эту работу?

XPT
источник

Ответы:

62

Вы можете использовать команду truncate :

truncate --size=1G test.txt

РАЗМЕР может быть указан как байты, КБ, К, МБ, М и т. Д. Я предполагаю, что вы можете вычислить желаемый размер вручную; если нет, вы можете использовать команду stat для получения информации о текущем размере файла.

ChrisInEdmonton
источник
Его документация (в информационном формате) от coreutils.
Кристиан Чиупиту
21
perl -we 'open( FILE, "< ./test.txt" ) && truncate( FILE, 8 ) && close(FILE);'

открывает файл для чтения. Однако для усечения файла вам необходимо изменить его, поэтому дескриптор файла только для чтения не будет работать. Вам нужно использовать режим «изменить» ( "+>").

Как побочный вопрос, меня всегда удивляет, когда люди позволяют системным вызовам молчать, а затем спрашивают, что пошло не так. Существенная часть диагностики проблемы смотрит на сообщении об ошибке производстве; даже если вы этого не понимаете, это делает жизнь намного проще для тех, кого вы просите о помощи.

Следующее было бы несколько более полезным:

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

хотя по общему признанию это только сообщило бы "неверный аргумент". Тем не менее, это полезная информация, которая могла бы привести вас к выводу, что режим открытия был неправильным (как это было для меня).

RICi
источник
3

Вы можете использовать, tailчтобы сократить последние 100000 байт, например:

tail -c 100000 file> file2

-c выводит последние 100000 байт файла, для дополнительных опций:

мужской хвост

Чтобы заменить исходный файл только что созданным файлом:

mv file2 file

Иван Малышев
источник
2

Ответ выше со ссылкой на усечение хорош. дд также сделает работу:

dd if=test.txt of=test2.txt bs=1 count=8
mv test2.txt test.txt
Джеймс Георгас
источник
1
Ключевая фраза - «до заданного размера» , скажем, 1000. Вместо этого я заменю ответ на вопрос с наибольшим количеством голосов, который работает на входе «на лету» - нет необходимости в промежуточном файле.
xpt
0

Существует совершенно другой способ сделать это, используя bash, используя программу ed. следующий скрипт сохранит только последние 5000 строк всех файлов, находящихся в указанном каталоге. это может быть легко изменено, чтобы зациклить несколько каталогов, изменить количество строк и т. д.

#!/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
Ричард
источник