"dd bs = 1 skip = N"이 아닌 지정된 오프셋에서 파일을 출력하는 방법은 무엇입니까?


28

dd if=somefile bs=1 skip=1337 count=313370001 바이트 읽기 및 쓰기를 사용하지 않는 것과 같은 효율적인 작업을 수행하는 방법 은 무엇입니까?

해결책은 다음과 같습니다.

  1. 간단하게 (단순하지 않은 경우이 작업을 수행하는 Perl oneliner를 작성할 수 있습니다)
  2. 큰 오프셋과 길이를 지원하려면 (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

dd가 사용중인 블록 크기를 변경하려고합니까?
cmorse

변경된 블록 크기 => 건너 뛰기와 카운트를위한 단위 변경
Vi.

답변:


37

이것은 그것을해야합니다 (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'.

추신 : 나는이 질문이 오래되었다는 것을 이해하고 질문이 원래 요청 된 후에이 플래그가 구현 된 것처럼 보이지만 관련 dd 검색에 대한 첫 번째 Google 검색 결과 중 하나이므로 새로운 것으로 업데이트하는 것이 좋지만 특색.


2

하나의 프로세스를 사용하여 모든 초기 바이트를 버리고 다른 바이트는 실제 바이트를 읽습니다. 예를 들면 다음과 같습니다.

echo Hello, World\! | ( dd of=/dev/null bs=7 count=1 ; dd bs=5 count=1 )

두 번째 dd는 효율적인 블록 크기로 입력을 읽을 수 있습니다. 이를 위해서는 추가 프로세스가 생성되어야합니다. OS에 따라 비용이 발생하지만 파일을 하나씩 읽어야하는 것보다 크기가 작을 수 있습니다 (매우 작은 파일이없는 경우에는 문제가 없습니다).


큰 오프셋과 카운트에 대해 잘 작동합니까 (즉, 너무 많은 메모리를 소비하지 않습니까)? dd if=/dev/sda bs=10000000001 | dd bs=255 count=1 | hd-> "dd : 유효하지 않은 숫자`10000000001 '"
Vi.

@Vi. 큰 오프셋을 건너 뛰려면 초기 읽기를 일련의 "이상적으로"(소스에 따라) 크기 블록 (16M)으로 수행 한 다음 메모리에있는 더 작은 크기의 블록 (512)을 삭제해야합니다. , 데이터를 "확대"하려면 블록 크기 (아래의 bs = 1)에 맞지 않는 홀수 부분을 버리고 원하는 블록을 읽습니다. 예를 들어 오프셋 10000000001에서 255 바이트를 읽으려고합니다. dd if=/dev/sda bs=16M skip=596 count=1 | dd bs=512 skip=1522 count=1 | (dd bs=1 count=1 of=/dev/null ; dd bs=255 count=1)
RolKau

확실히 read -n건너 뛰기 가 더 쉬울 까요? 그리고 head -c계산? 예를 들어 cat somefile | (read -n 1337; head -c 31337000)추가 프로세스를 생성하지 않고 수행 할 수 있습니다.exec 3<somefile; read -n 1337 -u 3; head -c 31337000 <&3
Gannet

1

대신 bs=1사용 bs=4096이상.


2
그러면 1337
Vi

1
아하, 그렇군요, 아마이 예제에서와 같이 예를 들어 간단한 파이썬 스크립트를 작성하는 쉬울 것 stackoverflow.com/questions/1035340/... 와 함께 f.seek(1337)사용하기 전에read(MY_CHUNK_SIZE)
ccpizza

가장 신뢰할 수있는 방법은 아마도 사용자 정의 실행 파일을 작성하는 것 같습니다. 일부 시스템에는 Python, Ruby 또는 Perl이 없습니다. : |
Trejkaz

1

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 #

파일을 16 진수로 보는 것이 아닙니다. 지정된 오프셋 (바이트)에서 파일의 내용 (예 : 어딘가에 복사)을 추출하는 것입니다.
Vi.
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.