dd: кілька вхідних файлів


14

Мені потрібно об'єднати шматки з двох файлів:

якби мені знадобилося об'єднати цілі файли, я можу просто зробити

cat file1 file2 > output

Але мені потрібно пропустити перший 1 Мб з першого файлу, і мені потрібно лише 10 Мб з другого файлу. Здається, робота dd.

dd if=file1 bs=1M count=99 skip=1 of=temp1
dd if=file2 bs=1M count=10 of=temp2
cat temp1 temp2 > final_output

Чи є можливість зробити це за один крок? тобто без потреби зберігати проміжні результати? Чи можу я використовувати декілька вхідних файлів dd?

Відповіді:


21

dd може написати також у stdout.

( dd if=file1 bs=1M count=99 skip=1
  dd if=file2 bs=1M count=10  ) > final_output

Це, мабуть, найкращий спосіб. Вихідний файл не закритий / повторно відкритий (як і у випадку oflag=append conv=notrunc), тому файлові системи, які затримують розподіл (наприклад, XFS), найменш імовірно, вирішать, що файл буде записаний тоді, коли ще потрібно ще щось.
Пітер Кордес

@PeterCordes - це хороший момент, але доки ddне вимагається sync, відкладений розподіл не повинен починатись негайно (якщо тільки пам'ять не є тісною, в цьому випадку жоден метод не відкладе розподіл).
Стівен Кітт

@StephenKitt: Ви, мабуть, праві. Я думав про спекулятивну перерозподіл XFS , де потрібно спеціально виявити шаблон закриття / повторного відкриття доступу (іноді його можна побачити для файлів журналів).
Пітер Кордес

3
В оболонках , як bashі mkshщо ні оптимізують з вил для останньої команди в субоболочке, ви можете зробити його трохи більш ефективним шляхом заміни подоболочки з командної групою. Для інших оболонок це не має значення, і підхід до підключення може бути навіть дещо ефективнішим, оскільки оболонці не потрібно зберігати та відновлювати stdout.
Стефан Шазелас

10

Я не думаю, що ви можете легко прочитати кілька файлів за один ddвиклик, але ви можете додати, щоб створити вихідний файл у кілька кроків:

dd if=file1 bs=1M count=99 skip=1 of=final_output
dd if=file2 bs=1M count=10 of=final_output oflag=append conv=notrunc

Вам потрібно вказати і те, conv=notruncі oflag=append. Перший уникає обрізання виводу, другий починає писати з кінця наявного файлу.


8

Майте на увазі , що ddє низькорівневим інтерфейсом до read(), write()і lseek()системний виклик. Ви можете його надійно використовувати лише для вилучення фрагментів даних із звичайних файлів, блокування пристроїв та деяких символьних пристроїв (наприклад /dev/urandom), тобто файлів, які read(buf, size)гарантовано повертаються до sizeтих пір, поки не буде досягнуто кінця файлу.

Для труб, розеток і більшості символьних пристроїв (як-от ttys) у вас немає такої гарантії, якщо ви не маєте read()розмір 1 або не використовуєте ddрозширення GNU iflag=fullblock.

Так чи:

{
  gdd < file1 bs=1M iflag=fullblock count=99 skip=1
  gdd < file2 bs=1M iflag=fullblock count=10
} > final_output

Або:

M=1048576
{
  dd < file1 bs=1 count="$((99*M))" skip="$M"
  dd < file2 bs=1 count="$((10*M))"
} > final_output

Або з оболонками з вбудованою підтримкою для оператора пошуку, наприклад ksh93:

M=1048576
{
  command /opt/ast/bin/head -c "$((99*M))" < file1 <#((M))
  command /opt/ast/bin/head -c "$((10*M))" < file2
}

Або zsh(якщо ви headпідтримуєте -cопцію тут):

zmodload zsh/system &&
{
  sysseek 1048576 && head -c 99M &&
  head -c 10M < file2
} < file1 > final_output

Вам справді потрібні цитати? Не завжди результат завжди буде цілим?
Стівен Пенні

@StevenPenny, залишаючи розширення без котирування, просить оболонку розділити + glob, що тут не має сенсу. Роздільна частина проводиться за поточним значенням $IFS. Це незалежно від змісту змінної / розширення. Дивіться також наслідки для безпеки забування процитувати змінну в оболонках bash / POSIX
Stéphane Chazelas

@ Stéphane Chazelas - у першому прикладі ви використовуєте gddзамість dd. Це помилка друку чи це навмисне?
Мартін Вегтер

3

З баш- ізмом та функціонально "марним використанням кота ", але найближчим до синтаксису, ОП використовує:

cat <(dd if=file1 bs=1M count=99 skip=1) \
    <(dd if=file2 bs=1M count=10) \
   > final_output

(Коли це було сказано, відповідь Стівена Кітта здається найбільш ефективним можливим методом.)


3
Строго кажучи, <(...)це кшизм, який zshі bashкопіюється.
Стефан Шазелас
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.