24

Как сделать что-то вроде 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

4 ответа4

34

Это должно сделать это (на 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 может читать ввод с любым размером блока, который вы считаете эффективным. Обратите внимание, что для этого требуется дополнительный процесс; в зависимости от вашей ОС это будет стоить, но, вероятно, будет меньше, чем необходимость считывать файлы по одному байту (если у вас нет очень маленького файла, в этом случае проблем не будет).

1

Вместо bs=1 используйте bs=4096 или более.

0

Вы можете попробовать команду 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 #

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .