dd : 여러 입력 파일


14

두 파일에서 청크를 연결해야합니다.

전체 파일을 연결 해야하는 경우 간단히 할 수 있습니다.

cat file1 file2 > output

그러나 첫 번째 파일에서 첫 번째 1MB를 건너 뛰고 두 번째 파일에서 10MB 만 원합니다. 의 직업인 것 같습니다 dd.

dd if=file1 bs=1M count=99 skip=1 of=temp1
dd if=file2 bs=1M count=10 of=temp2
cat temp1 temp2 > final_output

한 번에이 작업을 수행 할 수 있습니까? 즉, 중간 결과를 저장할 필요가 없습니까? 여러 입력 파일을 사용할 수 있습니까 dd?

답변:


21

dd stdout에도 쓸 수 있습니다.

( dd if=file1 bs=1M count=99 skip=1
  dd if=file2 bs=1M count=10  ) > final_output

아마도 가장 좋은 방법 일 것입니다. 출력 파일은 (와 마찬가지로) 닫히거나 다시 열리지 oflag=append conv=notrunc않으므로 할당이 지연된 파일 시스템 (예 : XFS)은 파일이 아직 더 많이 남아있을 때 파일이 작성되었다고 결정할 가능성이 가장 낮습니다.
Peter Cordes

@PeterCordes는 좋은 지적이지만 dd요구되지 않는 한 sync, 지연 된 할당은 어쨌든 즉시 시작되지 않아야합니다 (메모리가 빡빡하지 않으면 어떤 방법도 할당을 연기하지 않습니다).
Stephen Kitt

@StephenKitt : 당신 말이 맞을 것입니다. XFS의 추론 적 사전 할당 을 생각하고 있었는데 , 여기서 닫기 / 재 개설 액세스 패턴 (때로는 로그 파일에서 볼 수 있음)을 감지해야합니다.
Peter Cordes

3
같은 쉘에서 bashmksh서브 쉘의 마지막 명령의 포크를 최적화하지 않는, 당신은 명령 그룹과 서브 쉘을 대체하여이 약간 더 효율적으로 만들 수 있습니다. 다른 쉘의 경우 문제가되지 않으며, 쉘이 stdout을 저장하고 복원 할 필요가 없으므로 서브 쉘 접근 방식이 약간 더 효율적일 수도 있습니다.
Stéphane Chazelas

10

한 번의 dd호출로 여러 파일을 쉽게 읽을 수는 없지만 여러 단계로 출력 파일을 빌드하기 위해 추가 할 수 있습니다.

dd if=file1 bs=1M count=99 skip=1 of=final_output
dd if=file2 bs=1M count=10 of=final_output oflag=append conv=notrunc

당신은 모두를 지정해야 conv=notrunc하고 oflag=append. 첫 번째는 출력 잘림을 피하고 두 번째는 기존 파일의 끝에서 쓰기를 시작합니다.


8

마음에 베어 dd원시받는 인터페이스 read(), write()lseek()시스템 호출. 일반 파일, 블록 장치 및 일부 문자 장치 (예 :)에서 데이터 청크를 추출하는 데만 안정적으로 사용할 수 있습니다 /dev/urandom. 즉 , 파일 끝에 도달하지 않는 한 read(buf, size)반환 size되는 파일입니다.

파이프, 소켓 및 대부분의 문자 장치 (예 : ttys) read()의 경우 크기가 1이거나 GNU dd확장을 사용 하지 않으면 그러한 보장이 없습니다 iflag=fullblock.

그래서 :

{
  gdd < file1 bs=1M iflag=fullblock count=99 skip=1
  gdd < file2 bs=1M iflag=fullblock count=10
} > final_output

또는:

M=1048576
{
  dd < file1 bs=1 count="$((99*M))" skip="$M"
  dd < file2 bs=1 count="$((10*M))"
} > final_output

또는 다음과 같은 탐색 연산자를 기본적으로 지원하는 쉘을 사용합니다 ksh93.

M=1048576
{
  command /opt/ast/bin/head -c "$((99*M))" < file1 <#((M))
  command /opt/ast/bin/head -c "$((10*M))" < file2
}

또는 zsh( 여기에서 귀하 head-c옵션을 지원 한다고 가정 ) :

zmodload zsh/system &&
{
  sysseek 1048576 && head -c 99M &&
  head -c 10M < file2
} < file1 > final_output

당신은 정말로 따옴표가 필요합니까? 결과가 항상 정수가 아닙니까?
Steven Penny

@StevenPenny, 확장을 인용하지 않은 채로두면 쉘이 분할 + glob하도록 요청합니다. 의 현재 값에 대해 분할 된 부분입니다 $IFS. 변수 / 확장 내용에 관계없이 적용됩니다. 참조 bash는 / POSIX 쉘에서 변수를 인용 망각의 보안에 미치는 영향
스테판 Chazelas가를

@ Stéphane Chazelas-첫 번째 예에서는 gdd대신 사용하고 dd있습니다. 오타입니까, 아니면 의도적인가요?
Martin Vegter

3

A를 bash는 주의 및 기능 "의 쓸모없는 사용 고양이 "하지만 구문에 가장 가까운 영업 이익의 용도 :

cat <(dd if=file1 bs=1M count=99 skip=1) \
    <(dd if=file2 bs=1M count=10) \
   > final_output

(즉, Stephen Kitt의 답변이 가장 효율적인 방법 인 것 같습니다 .)


3
엄밀히 말하면, <(...)A는 kshism 모두 zshbash복사됩니다.
Stéphane Chazelas
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.