Как сделать что-то подобное dd if=somefile bs=1 skip=1337 count=31337000
, но эффективно, не используя 1-байтовые чтения и записи?
Ожидается следующее решение:
- Чтобы было проще (для непростых я могу написать однострочник на Perl, который это сделает)
- Для поддержки больших смещений и длин (поэтому хаки с размером блока в 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 #