특정 범위의 데이터를 가져오는 dd 명령

특정 범위의 데이터를 가져오는 dd 명령

dd명령 에서는 skip파일에서 n 바이트 건너뛰기를 사용할 수 있습니다. n번째 바이트부터 파일의 끝까지 복사됩니다. 하지만 1228에서 1331로 이진 데이터를 복사하고 싶습니다. ddLinux에서 이를 달성하는 방법은 무엇입니까 ?

답변1

count복사할 바이트 수를 지정하는 데 사용됩니다 . 계산을 수행하려면 쉘을 사용하십시오. ibs=1입력 블록 크기를 1로 설정하는 데 사용되므로 skip및 모두 count바이트 단위로 지정됩니다.

 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단순히 사용할 이유가 없습니다.. 간단한 head합계 tail조합이면 충분합니다(GNU 도구 필요).

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

답변3

방금 공통 스크립트 dd-file-range.sh를 완료했습니다. dd-filescope.sh

한 파일에서 다른 파일로 바이트 범위를 복사하는 데 사용됩니다.
Linux 커널-5.3 또는 FreeBSD-13의 copy_file_range(2) 시스템 호출과 마찬가지로
다음도 참조하세요.리눅스 copye_file_range()그리고FreeBSD 복사_파일_범위()

또한 최신 Linux 배포판에서는 dd-file-range.sh 대신 xfs_io->copy_range 하위 명령을 사용할 수도 있습니다.

용법:

$ 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

관련 정보