Як підкласти файл до потрібного розміру?


15

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

Як я проклав його?

Схоже, це не працює:

cp smallfile.img largerfile.img
dd if=/dev/zero of=largerfile.img bs=1 count=262144

2
@terabyte; Ви хочете фізичне набивання або логічне набивання? Іншими словами; чи повинен файл містити лише розмір 16777216 (і може містити отвори) або він також повинен займати таку кількість пам’яті на диску? - До речі, вибираючи bs=1після прибуття ddв моєму досвіді дуже виконання дорого.
Яніс

5
truncate -s 16M thefile
frostschutz

4
@frostschutz, що була б гарною відповіддю, ти це розмістиш як відповідь.
дероберт

@derobert, Що з користувачем сайту StackExchange публікують законно, прості відповіді як коментарі?
користувач1717828

@ user1717828 не впевнений, напевно, добре питання для мета.
дероберт

Відповіді:


10

Видаліть of=largerfile.txtі додайте stdout до файлу:

dd if=/dev/zero bs=1 count=262144 >> largerfile.txt

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

3
Правильно. У цьому випадку truncate -s +262144 largerfile.txtтакож буде швидко.
don_crissti

4

Найкращий прихильник тут - Джаніс (вище), тому що він дозволяє забути про поточний розмір файлу та прокладати безпосередньо до потрібного розміру без розрахунку.

Він також використовує розріджені файли, яких додавання / dev / zero не дає.

Хоча відповідь може бути більш охайною, оскільки 'count' може бути 0, і ви все одно отримаєте прокладку:

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

(Редагувати: це правильно для GNU dd, але поведінка count=0залежить від платформи, див. Коментарі)


Ви помиляєтеся: не count=0вказано, але зазвичай таке ж, як і коли не countбуло вказано жодного параметра. Більше проблем: ddобрізає файл до 16777216 байт, але якщо ви сподіваєтесь, що це створить дірку в кінці, ви помиляєтесь, оскільки спершу потрібно буде записати дані після цього, а пізніше обрізати його до розміру, який не містить даних .
schily

count = 0 - це не що інше, як вказати параметр "count". Ви говорите, що dd if=/dev/zero of=somefileце те саме, що dd if=/dev/zero of=somefile count=0? Спробуй це.
PeteC

Звичайно! count=0 це те ж саме , як якщо б ви не вказали параметр лічильника на всіх. Це справедливо принаймні для всіх реалізацій, які були отримані з оригінальних джерел. Спробуйте, схоже, ви ніколи не працювали з оригінальною ddкомандою.
schily

Я не можу знайти жодної документації, яка б вказувала 0 як унікальне значення для countзначення "ігнорувати цей параметр". Ви можете знайти будь-яку? Без такої документації count=0означає "записувати нульові блоки", і будь-яке відхилення від цього - помилка ... (оригінальні джерела чи ні).
PeteC

1
Це була документація POSIX з травня 2015 року, коли текст, що не було вказано, було виправлено.
schily

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 для пошуку до позиції перед цим байтом. Ми знімаємо іншу, оскільки позиція пошуку нульова.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.