如何以合理的速度复制二进制文件的任意部分?

Dim*_*ims 9 dd

如何以合理的速度复制二进制文件的任意部分?

显然,ddwithbs=1非常慢,而设置bs为另一个值则无法复制任意部分。

这是错的吗?可以用 做吗dd?如果不是的话,那么工具是什么?

例如,这个命令,

dd if="$img" of=tail.bin bs=2147483648 skip=1 status=progress
Run Code Online (Sandbox Code Playgroud)

复制错误的尾部。

而这个命令,

dd if="$img" of=tail.bin bs=1 skip=2147483648 status=progress
Run Code Online (Sandbox Code Playgroud)

非常慢。

fro*_*utz 21

GNU dd 支持count_bytes, seek_bytes,skip_bytes标志。这允许您使用具有任意偏移和大小的高性能块大小选择。

如果您指定字节单位,GNU dd 自版本 9.1 起默认执行此操作。

引用coreutils/NEWS

如果块计数以“B”结尾,dd 现在计算字节而不是块。例如,“dd count=100KiB”现在复制 100 KiB 数据,而不是 102,400 个数据块。因此,标志 count_bytes、skip_bytes 和eek_bytes 已过时并且不再记录,尽管它们仍然有效。

另一种选择是创建具有所需偏移和尺寸限制的循环设备。这适用于本身不支持任意偏移的 dd (或任何其他程序)。

或者,您也可以考虑仅复制 bs=1 的部分第一个/最后一个块以及具有所需较大块大小的中间段。

  • 最后一段虽然是一个可行的建议,但编码起来却不必要地复杂。 (2认同)

Whi*_*Owl 8

尝试这个:

tail -c +$FROM file.dat | head -c $LENGTH > file1.dat
Run Code Online (Sandbox Code Playgroud)

只需根据需要分配 FROM 和 LENGTH 即可。请注意, 的编号tail是基于1 的,例如tail -c +4表示从第四个字节开始,即跳过前三个字节。

举个例子:

$ printf 'abcdefghijklmnopqrstuvwxyz\n' > test.txt
$ tail -c +4 test.txt | head -c 6; echo
defghi
Run Code Online (Sandbox Code Playgroud)

  • 如果 `$FROM` 可能很大,那么 `tail -c +$FROM file.dat | 可能会更有效。头 -c $LENGTH`。这样,“tail”可以搜索第一个“$FROM”字节并从那里开始读取(并在“head”停止读取更多数据后收到 SIGPIPE 时停止)。 (4认同)
  • 这里的参数是否从零开始、TO 不包括、FROM 包括在内? (2认同)
  • @Dims 阅读“man head”和“man tail”,您可以看到“head -c 5”将为您提供源的前五个字节,并通过管道传输到“tail -c +3”(或者实际上是“head -c”) 3`) 会给你前三个字节 (2认同)