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

28

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

Ожидается решение:

  1. Чтобы быть простым (для непростых я могу написать некоторый Perl oneliner, который сделает это)
  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
Vi.
источник
Вы пытаетесь изменить размер блока, который использует dd?
см
Измененный размер блока => измененные единицы для пропуска и подсчета
Vi.

Ответы:

37

Это должно сделать это (на 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'.

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

Фабиано
источник
2

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

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

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

RolKau
источник
Будет ли это работать хорошо (т.е. не занимать слишком много памяти) для больших смещений и счетчиков? dd if=/dev/sda bs=10000000001 | dd bs=255 count=1 | hd-> «ДД: недействительный номер« 10000000001 »»
Vi.
@Vi. Если вы хотите пропустить огромное смещение, то вы должны выполнить начальное чтение как серию блоков «идеально» (в зависимости от вашего источника) размера (16M), а затем отбросить серию блоков меньшего размера (512), которые будут в памяти , чтобы «увеличить» ваши данные, прежде чем вы удалите нечетный раздел, который не соответствует размеру блока (bs = 1 ниже), а затем прочитаете нужный вам блок. Например, вы хотите прочитать 255 байтов со смещения 10000000001: dd if=/dev/sda bs=16M skip=596 count=1 | dd bs=512 skip=1522 count=1 | (dd bs=1 count=1 of=/dev/null ; dd bs=255 count=1)
RolKau
Конечно, было бы проще использовать, read -nчтобы пропустить? А потом head -cсчитать? Например, cat somefile | (read -n 1337; head -c 31337000)вы могли бы сделать это, не вызывая дополнительного процесса:exec 3<somefile; read -n 1337 -u 3; head -c 31337000 <&3
Gannet
1

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

ccpizza
источник
2
Затем он будет читать со смещения 1337 * 4096 вместо 1337
Vi.
1
Ага, я вижу, тогда, вероятно, будет проще написать простой скрипт на Python, например, как в этом примере stackoverflow.com/questions/1035340/… с f.seek(1337)перед использованиемread(MY_CHUNK_SIZE)
ccpizza
Похоже, самый надежный способ - написать собственный исполняемый файл. Некоторые системы не имеют Python, Ruby или даже Perl. : |
Трейказ
1

Вы можете попробовать команду 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 #
Сараванан Паланисами
источник
Дело не в просмотре файла в шестнадцатеричном формате. Речь идет о извлечении содержимого файла (например, для его копирования куда-либо) из указанного смещения в байтах.
Ви.