Сегодня мне пришлось удалить первые 1131 байт из смешанного текстового / двоичного файла размером 800 МБ, отфильтрованного дампа подрывной деятельности, который я взламываю для нового хранилища. Какой лучший способ сделать это?
Для начала я попробовал
dd bs=1 skip=1131 if=filtered.dump of=trimmed.dump
но после пропуска это копирует оставшуюся часть файла байт за раз, то есть очень медленно. В итоге я решил, что мне нужно 405 байт, чтобы округлить до трех блоков из 512, которые я мог пропустить
dd if=/dev/zero of=405zeros bs=1 count=405
cat 405zeros filtered.dump | dd bs=512 skip=3 of=trimmed.dump
который завершился довольно быстро, но, должно быть, был более простой / лучший способ? Есть ли другой инструмент, о котором я забыл? Спасибо!
dd
это правильный инструмент для работы - похоже, вы придумали хорошее и элегантное решение вашей проблемы.Ответы:
Вы можете переключать bs и пропускать опции:
Таким образом, операция может выиграть от большего блока.
В противном случае вы можете попробовать использовать tail (хотя использовать его с двоичными файлами небезопасно):
Наконец, вы можете использовать 3 экземпляра dd, чтобы написать что-то вроде этого:
где первый дд выводит свой стандартный вывод filter.dump; второй просто читает 1131 байт и выбрасывает их; затем последний читает из своего стандартного ввода оставшиеся байты фильтрованного файла Filter.dump и записывает их в trimmed.dump.
источник
bs=1131 skip=1
хотя: - /Не уверен, когда
skip_bytes
был добавлен, но чтобы пропустить первые 11 байтов, у вас есть:Где
iflag=skip_bytes
указывает dd интерпретировать значениеskip
параметра как байты вместо блоков, что делает его простым.источник
iflag=skip_bytes skip=1234 bs=1M
Вы можете использовать вложенную оболочку и два
dd
вызова, например:источник
Если файловая система и ядро Linux поддерживают ее, то вы можете попробовать,
fallocate
если хотите внести изменения на месте: в лучшем случае ввода-вывода данных вообще нет:где
<magic>
зависит от файловой системы, версии Linux и типа файла (FALLOC_FL_COLLAPSE_RANGE
илиFALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE
может использоваться внутри ).источник
Вы должны использовать
count=0
- это просто,lseek()
когда это возможно.Нравится:
dd
будетlseek()
дескриптор входного файла со смещением 1131 байт, а затемcat
просто скопирует все, что осталось для вывода.источник
Еще один способ удалить начальные байты из файла (
dd
вообще не используя ) - использоватьxxd
иsed
илиtail
соответственно.источник
@maxschlepzig просит онлайн лайнера. Вот один в Perl. Требуется 2 аргумента: от байта и длины. Входной файл должен быть задан как «<», а вывод будет на stdout:
Если длина больше, чем файл, остальная часть файла будет скопирована.
На моей системе это обеспечивает 3,5 ГБ / с.
источник
dd
не гарантирует полное чтение. Попробуйте: да | дд бс = 1024к кол = 10 | wc unix.stackexchange.com/questions/17295/…