Как дополнить файл до нужного размера?

15

У меня есть файл, который я хочу заполнить, пока он не достигнет 16 МБ (16777216 байт). В настоящее время это 16515072 байта. Разница составляет 262144 байта.

Как мне это дополнить?

Это не похоже на работу:

cp smallfile.img largerfile.img
dd if=/dev/zero of=largerfile.img bs=1 count=262144
tarabyte
источник
2
@terabyte; Вы хотите физическое заполнение или логическое заполнение? Другими словами; должен ли файл иметь размер только 16777216 (и может содержать дыры) или он также должен занимать такой объем памяти на диске? - Кстати, выбор bs=1в ddмоем опыте очень дорогой.
Янис
5
truncate -s 16M thefile
frostschutz
4
@frostschutz, это был бы хороший ответ, если бы вы опубликовали его как ответ.
Дероберт
@derobert, что за пользователи сайта StackExchange публикуют в комментариях легальные, простые ответы?
user1717828
@ user1717828 не уверен, наверное, хороший вопрос для мета.
Дероберт

Ответы:

10

Удалите of=largerfile.txtи добавьте стандартный вывод в файл:

dd if=/dev/zero bs=1 count=262144 >> largerfile.txt
Outurnate
источник
1
seekэто правильный вариант здесь.
0
15

Помимо ответов для получения физического отступа, вы также можете оставить большую часть пространства дополнения в файле просто пустым («дыры»), seekперейдя в новую конечную позицию файла и написав один символ:

dd if=/dev/zero of=largerfile.txt bs=1 count=1 seek=16777215

(который имеет преимущество в том, что он гораздо более производительный, особенно с ним bs=1, и не занимает много дополнительного дискового пространства).

Этот метод работает даже без добавления каких-либо символов, используя if=/dev/nullконечный желаемый размер файла:

dd if=/dev/null of=largerfile.txt bs=1 count=1 seek=16777216

Производительный вариант решения с физическим заполнением, которое использует блоки большего размера:

padding=262144 bs=32768 nblocks=$((padding/bs)) rest=$((padding%bs))
{
  dd if=/dev/zero bs=$bs count=$nblocks
  dd if=/dev/zero bs=$rest count=1
} 2>/dev/null >>largerfile.txt
Janis
источник
3
Верный. В этом случае truncate -s +262144 largerfile.txtтакже будет быстро.
don_crissti
4

Лучшим ответом здесь является Janis's (выше), потому что он позволяет забыть о текущем размере файла и заполнить его непосредственно до нужного размера без каких-либо вычислений.

Он также использует разреженные файлы, а добавление / dev / zero - нет.

Ответ может быть более аккуратным, потому что 'count' может быть равен 0, и вы все равно получаете заполнение:

dd if=/dev/null of=largerfile.txt bs=1 count=0 seek=16777216

(Изменить: это правильно для GNU dd, но поведение count=0зависит от платформы, см. Комментарии)

PeteC
источник
Вы ошибаетесь: count=0не countуказан , но, как правило, такой же, как когда не был указан параметр. Больше проблем: ddусекает файл до 16777216 байт, но если вы надеетесь, что это создает дыру в конце, вы ошибаетесь, поскольку вам сначала нужно будет записать данные после дыры, а затем усечь их до размера, который не содержит данных ,
Шили
count = 0 совсем не похоже на указание параметра no count. Вы говорите, что dd if=/dev/zero of=somefileэто так же, как dd if=/dev/zero of=somefile count=0? Попытайся.
PeteC
Конечно! count=0 так же, как если бы вы вообще не указали параметр count. Это верно по крайней мере для всех реализаций, которые были получены из оригинальных источников. Попробуйте, кажется, вы никогда не работали с оригинальной ddкомандой.
Шили
Я не могу найти какую-либо документацию, которая определяет 0 как уникальное значение для countзначения «игнорировать этот параметр». Вы можете найти что-нибудь? Без такой документации count=0означает «записать нулевые блоки», и любое отклонение от этого является ошибкой ... (первоисточники или нет).
Пит
1
Это была документация POSIX до мая 2015 года, когда был исправлен недостаточно уточненный текст.
Шили
1

Вы должны использовать dd? Если вы хотите, чтобы файл имел определенную (логическую) длину, просто запишите ноль в нужную позицию. Байты между предыдущим концом и записанным байтом будут отображаться как имеющие нулевые байты. Вот пример использования Perl.

$ echo Hello > file
$ ls -l file
-rw-r--r-- 1 user group 6 Apr 16 22:59 file
$ perl -le 'open(my $f,"+<","file"); seek($f, 16777216 - 2, 0); print $f "\0"'
$ ls -ln file
-rw-r--r-- 1 user group 16777216 Apr 16 22:59 file

Почему «- 2» в строке? Сценарий запишет байт, поэтому мы вычитаем 1 для поиска позиции перед этим байтом. Мы снимаем другую, потому что позиция поиска индексируется нулем.

BowlOfRed
источник