Как вывести файл с указанного смещения, а не «dd bs=1 skip=N»?

Как вывести файл с указанного смещения, а не «dd bs=1 skip=N»?

Как сделать что-то подобное dd if=somefile bs=1 skip=1337 count=31337000, но эффективно, не используя 1-байтовые чтения и записи?

Ожидается следующее решение:

  1. Чтобы было проще (для непростых я могу написать однострочник на Perl, который это сделает)
  2. Для поддержки больших смещений и длин (поэтому хаки с размером блока в dd не помогут)

Частичное решение (недостаточно простое, попытка сделать то же самое с длиной сделает задачу еще сложнее):

dd if=somefile bs=1000 skip=1 count=31337 | { dd bs=337 count=1 of=/dev/null; rest_of_pipeline; }
# 1337 div 1000 and 1337 mod 1000

решение1

Это должно сработать (в gnu dd):

dd if=somefile bs=4096 skip=1337 count=31337000 iflag=skip_bytes,count_bytes

Если вы seek=также используете , вы также можете рассмотреть oflag=seek_bytes.

От info dd:

`count_bytes'
      Interpret the `count=' operand as a byte count, rather than a
      block count, which allows specifying a length that is not a
      multiple of the I/O block size.  This flag can be used only
      with `iflag'.

`skip_bytes'
      Interpret the `skip=' operand as a byte count, rather than a
      block count, which allows specifying an offset that is not a
      multiple of the I/O block size.  This flag can be used only
      with `iflag'.

`seek_bytes'
      Interpret the `seek=' operand as a byte count, rather than a
      block count, which allows specifying an offset that is not a
      multiple of the I/O block size.  This flag can be used only
      with `oflag'.

P.S.: Я понимаю, что этот вопрос старый, и, похоже, эти флаги были реализованы после того, как вопрос был изначально задан, но поскольку это один из первых результатов Google по связанному с dd поиску, который я сделал, я подумал, что было бы неплохо обновить его, добавив новую функцию.


Примечание: этот ответ применим только кGNU дд, используемый большинством дистрибутивов Linux, он является частьюПакет GNU coreutilsэта функция была представлена ​​в версии coreutils 8.16 (2012-03-26, через пару месяцев после того, как был дан ответ на исходный вопрос).

Примечание дляПользователи Mac: MacOS использует вариант утилит unix на основе bsd (в основном по причинам лицензирования), но версии утилит unix GNU в целом имеют гораздо более активную разработку и обычно имеют гораздо больше функций. Вы можете установить GNU coreutils на Mac с помощьюДомашнее пиво: brew install coreutils.

решение2

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

echo Hello, World\! | ( dd of=/dev/null bs=7 count=1 ; dd bs=5 count=1 )

Второй ddможет читать входные данные с любым размером блока, который вы сочтете эффективным. Обратите внимание, что это требует создания дополнительного процесса; в зависимости от вашей ОС, это потребует затрат, но, вероятно, это меньше, чем читать файлы по одному байту (если только у вас не очень маленький файл, в этом случае проблем не возникнет).

решение3

Вместо bs=1использования bs=4096или более.

решение4

Вы можете попробовать команду hexdump:

hexdump  -v <File Path> -c -n <No of bytes to read> -s <Start Offset>

Если вы просто хотите увидеть содержимое:

#/usr/bin/hexdump -v -C mycorefile -n 100 -s 100
00000064 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 
00000074 00 00 00 00 01 00 00 00 05 00 00 00 00 10 03 00 |................| 
00000084 00 00 00 00 00 00 40 00 00 00 00 00 00 00 00 00 |......@.........| 
00000094 00 00 00 00 00 00 00 00 00 00 00 00 00 a0 03 00 |................| 
000000a4 00 00 00 00 00 10 00 00 00 00 00 00 01 00 00 00 |................| 
000000b4 06 00 00 00 00 10 03 00 00 00 00 00 00 90 63 00 |..............c.| 
000000c4 00 00 00 00 |....| 
000000c8 #

Связанный контент