dd命令获取特定范围的数据

dd命令获取特定范围的数据

dd命令中,我们可以使用skip跳过文件中的n个字节。从第 n 个字节到文件末尾被复制。但我只想将二进制数据从 1228 复制到 1331。如何在ddLinux 上实现这一目标?

答案1

使用count指定要复制的字节数。使用shell进行计算。用于ibs=1将输入块大小设置为 1,因此skipcount均以字节为单位指定。

 dd ibs=1 skip=1228 count=$((1331-1228+1))

由于 1228 和 1331-1228+1 都是 4 的倍数,因此可以将输入块大小设置为 4,这将使事情变得更加高效,但除非要使用大量次数,否则优化将会丢失喧嚣中。其他事情,比如预先计算结果,1331-1228+1应该首先完成。

 dd ibs=4 skip=$((1228/4)) count=$(((1331-1228+1)/4))

答案2

dd根本没有理由使用。一个简单的headtail组合就足够了(需要 GNU 工具):

head -c 1331 file | tail -c $((1331-1228+1)) 

答案3

刚刚完成了一个常用脚本dd-file-range.sh: dd-文件范围.sh

用于将字节范围从一个文件复制到另一个文件。
就像 linux kernel-5.3 或 FreeBSD-13 上的系统调用 copy_file_range(2) 一样,
另请参阅:linux copye_file_range()FreeBSD copy_file_range()

并且还可以在较新的 Linux 发行版中使用 xfs_io->copy_range 子命令来代替 dd-file-range.sh

用法:

$ dd-file-range.sh
Usage: dd-file-range.sh <ifile[:skip_offset[:len]]> [ofile[:seek_offset]] [-bs=BSIZE] [-sep=<seperator>] [-log=<0|1|2>]
#Comment: if 'skip_offset' start with '['; trate it as 'start' #((start=skip_offset+1))
#Comment: if 'len' has a suffix ']'; trate it as 'end' #((end=skip_offset+len))
#Comment: e.g: ifile:5:5 <=is equivalent to=> ifile:[6:10]

Examples:
  dd-file-range.sh ifile:8192:512  ofile
  dd-file-range.sh ifile::4096     ofile:1024
  dd-file-range.sh ifile:4                     #output to stdout
  dd-file-range.sh <(cat):4  ofile             #read from stdin
  dd-file-range.sh ifile::4  ifile:10          #copy data within same file 

对于原来的问题,我们可以使用 dd-file-range.sh ,例如:

$ dd-file-range.sh kiss-vm:$((1228-1)):$((1331-1228+1))
$ #or simple
$ dd-file-range.sh kiss-vm:[1228:1331]

不同bs的性能测试:

$ ls -lh kiss-vm.gif 
-rw-r--r-- 1 yjh fs-qe 4.0M May 12  2021 kiss-vm.gif
$ time dd-file-range.sh kiss-vm.gif:1981 b:1981 -ver=old -bs=$((128*1024))
real    0m0.023s
user    0m0.005s
sys 0m0.026s
$ time dd-file-range.sh kiss-vm.gif:1981 b:1981 -ver=old -bs=$((64*1024))
real    0m0.023s
user    0m0.007s
sys 0m0.022s
$ time dd-file-range.sh kiss-vm.gif:1981 b:1981 -ver=old #default BS == $((16*1024))
real    0m0.022s
user    0m0.003s
sys 0m0.025s
$ time dd-file-range.sh kiss-vm.gif:1981 b:1981 -ver=old -bs=$((8*1024))
real    0m0.022s
user    0m0.005s
sys 0m0.023s
$ time dd-file-range.sh kiss-vm.gif:1981 b:1981 -ver=old -bs=$((4*1024))
real    0m0.023s
user    0m0.008s
sys 0m0.022s
$ time dd-file-range.sh kiss-vm.gif:1981 b:1981 -ver=old -bs=1024
real    0m0.024s
user    0m0.005s
sys 0m0.028s
$ time dd-file-range.sh kiss-vm.gif:1981 b:1981 -ver=old -bs=512
real    0m0.039s
user    0m0.006s
sys 0m0.048s
$ time dd-file-range.sh kiss-vm.gif:1981 b:1981 -ver=old -bs=256
real    0m0.037s
user    0m0.010s
sys 0m0.044s
$ time dd-file-range.sh kiss-vm.gif:1981 b:1981 -ver=old -bs=128
real    0m0.046s
user    0m0.012s
sys 0m0.057s
$ time dd-file-range.sh kiss-vm.gif:1981 b:1981 -ver=old -bs=64
real    0m0.072s
user    0m0.011s
sys 0m0.102s
$ time dd-file-range.sh kiss-vm.gif:1981 b:1981 -ver=old -bs=32
real    0m0.129s
user    0m0.014s
sys 0m0.199s
$ time dd-file-range.sh kiss-vm.gif:1981 b:1981 -ver=old -bs=16
real    0m0.275s
user    0m0.049s
sys 0m0.425s
$ time dd-file-range.sh kiss-vm.gif:1981 b:1981 -ver=old -bs=8
real    0m0.460s
user    0m0.077s
sys 0m0.707s
$ time dd-file-range.sh kiss-vm.gif:1981 b:1981 -ver=old -bs=4
real    0m1.278s
user    0m0.208s
sys 0m2.082s
$ time dd-file-range.sh kiss-vm.gif:1981 b:1981 -ver=old -bs=2
real    0m1.841s
user    0m0.294s
sys 0m2.846s
$ time dd-file-range.sh kiss-vm.gif:1981 b:1981 -ver=old -bs=1
real    0m3.924s
user    0m0.610s
sys 0m6.227s

相关内容