큰 파일을 복사하지 않고 서로 추가


41

디스크에 남은 여유 공간이 각각 10G 인 5 개의 거대한 파일 (file1, file2, .. file5)이 있으며이 모든 파일을 하나로 연결해야합니다. 원본 파일을 유지할 필요는 없으며 마지막 파일 만 보관하십시오.

일반적인 연결은 함께가는 cat파일을 순서대로 file2.. file5:

cat file2 >> file1 ; rm file2

불행히도이 방법은 내가 가지고 있지 않은 최소 10G 여유 공간이 필요합니다. 실제로 복사하지 않고 파일을 연결하는 방법이 있지만 파일 시스템에 어떻게 든 file1이 원래 file1 끝에서 끝나지 않고 file2 시작에서 계속된다고 알려주십시오.

추신. 중요한 경우 파일 시스템은 ext4입니다.


2
해결책을 찾고 싶지만 파일 시스템을 직접 엉망으로 만들지 않으면 불가능하다고 생각합니다.
Kevin

1
왜 이렇게 큰 실제 파일이 하나 있어야합니까? 현재 답변에서 알 수 있듯이 연결을 피할 수 있기 때문에 묻습니다.
liori

6
@rush : 그러면이 답변이 도움이 될 것입니다 : serverfault.com/a/487692/16081
liori

1
장치 매퍼의 대안으로, 효율성은 떨어지지 만 구현하기 쉽고 분할 가능한 장치를 생성하며 원격 시스템에서 사용할 수있는 "멀티"모드를 사용하는 것입니다 nbd-server.
Stéphane Chazelas 2016 년

1
나는 이것이 시원해야한다고 생각할 때 항상 바보라고 부릅니다.
n611x007

답변:


19

AFAIK (불행히도) 처음부터 파일을 자르는 것은 불가능합니다 (표준 툴에서는 가능하지만 syscall 레벨 은 여기를 참조하십시오 ). 그러나 약간의 복잡성을 추가하면 일반 잘림을 사용할 수 있습니다 (드문 파일과 함께). 사이에 모든 데이터를 쓰지 않고도 대상 파일의 끝에 쓸 수 있습니다.

먼저 두 파일이 모두 정확히 5GiB (5120MiB)이고 한 번에 100MiB를 이동한다고 가정하겠습니다. 당신은 다음으로 구성된 루프를 실행합니다

  1. 소스 파일의 끝에서 대상 파일의 끝으로 하나의 블록 복사 (사용 된 디스크 공간 늘리기)
  2. 소스 파일을 한 블록 씩 잘라 내기 (디스크 공간 확보)

    for((i=5119;i>=0;i--)); do
      dd if=sourcefile of=targetfile bs=1M skip="$i" seek="$i" count=1
      dd if=/dev/zero of=sourcefile bs=1M count=0 seek="$i"
    done
    

그러나 작은 테스트 파일을 먼저 사용해보십시오. 제발 ...

파일 크기가 같거나 블록 크기의 배수가 아닐 수 있습니다. 이 경우 오프셋 계산이 더 복잡해집니다. seek_bytes그리고 skip_bytes나서 사용해야합니다.

이것이 당신이 가고 싶지만 세부 사항에 대한 도움이 필요하다면 다시 요청하십시오.

경고

에 따라 dd블록 크기 결과 파일은 조각의 악몽이 될 것입니다.


이것이 파일을 연결하는 가장 적합한 방법 인 것 같습니다. 충고에 감사하다.
돌진

3
스파 스 파일 지원이 없으면 두 번째 파일을 블록 단위로 뒤집은 다음 마지막 블록을 제거하고 두 번째 파일에 추가하면됩니다.
ratchet freak

1
나는 이것을 시도하지는 않았지만 (내가하려고하지만) seann.herdejurgen.com/resume/samag.com/html/v09/i08/a9_l1.htm 은이 알고리즘을 구현한다고 주장하는 Perl 스크립트입니다.
zwol

16

프로그램이 여러 파일을 처리 할 수없는 경우 파일을 하나의 파일로 묶는 대신 명명 된 파이프를 사용하여 단일 파일을 시뮬레이션 할 수 있습니다.

mkfifo /tmp/file
cat file* >/tmp/file &
blahblah /tmp/file
rm /tmp/file

Hauke가 제안한 것처럼 losetup / dmsetup도 작동 할 수 있습니다. 빠른 실험; 나는 'file1..file4'를 만들었고 약간의 노력으로 다음을 수행했습니다.

for i in file*;do losetup -f ~/$i;done

numchunks=3
for i in `seq 0 $numchunks`; do
        sizeinsectors=$((`ls -l file$i | awk '{print $5}'`/512))
        startsector=$(($i*$sizeinsectors))
        echo "$startsector $sizeinsectors linear /dev/loop$i 0"
done | dmsetup create joined

그런 다음 / dev / dm-0에는 파일을 내용으로 사용하는 가상 블록 장치가 포함됩니다.

나는 이것을 잘 테스트하지 못했습니다.

또 다른 편집 : 파일 크기는 512로 균등하게 나눠야합니다. 그렇지 않으면 일부 데이터가 손실됩니다. 그렇다면 괜찮습니다. 나는 그가 또한 아래에 언급 한 것을 본다.


안타깝게도이 파일을 한 번 읽는 것이 좋습니다. 불행히도 fifo를 앞뒤로 건너 뛸 수 없습니다. 그렇지 않습니까?
돌진

7
@rush 최상의 대안은 각 파일에 루프 장치를 배치하고이를 dmsetup가상 블록 장치로 결합하는 것입니다 (일반 탐색 작업은 허용하지만 추가 또는 자르기는 허용하지 않음). 첫 번째 파일의 크기가 512의 배수가 아닌 경우 불완전한 마지막 섹터와 첫 번째 바이트를 두 번째 파일 (총 512)에서 세 번째 파일로 복사해야합니다. 그러면 두 번째 파일의 루프 장치가 필요합니다 --offset.
Hauke ​​Laging

우아한 솔루션. 또한 첫 번째 파일의 크기가 512의 배수가 아닌 경우 문제를 해결하는 방법을 제안하는 Hauke ​​Laging에게 +1
Olivier Dulac

9

사용 가능한 여유 공간만큼 많은 데이터를 묶음으로 복사하는 것을 작성해야합니다. 다음과 같이 작동합니다.

  • 읽기 전에 올바른 위치를 찾아서 file2사용하여 데이터 블록을 pread()읽습니다.
  • 에 블록을 추가하십시오 file1.
  • fcntl(F_FREESP)에서 공간을 할당 해제하는 데 사용 합니다 file2.
  • 반복

1
나도 알아 ...하지만 코드 작성과 관련이없는 방법을 생각할 수 없었으며 내가 쓴 것을 쓰는 것이 아무것도 쓰는 것이 더 낫다는 것을 알았습니다. 나는 처음부터 시작하는 당신의 영리한 속임수를 생각하지 않았습니다!
Celada

너도 끝에서 시작하지 않으면 작동하지 않습니까?
Hauke ​​Laging

아니요 fcntl(F_FREESP). 파일의 주어진 바이트 범위와 관련된 공간을 비우기 때문에 처음부터 작동 합니다 (드문 드문합니다).
Celada

꽤 괜찮은데. 그러나 매우 새로운 기능인 것 같습니다. 내 fcntl맨 페이지 (2012-04-15) 에는 언급되어 있지 않습니다 .
Hauke ​​Laging

4
@HaukeLaging F_FREESP는 Solaris입니다. Linux (2.6.38부터)에서 fallocatesyscall 의 FALLOC_FL_PUNCH_HOLE 플래그입니다 . 새로운 버전의 fallocate 유틸리티 util-linux는 이에 대한 인터페이스를 가지고 있습니다.
Stéphane Chazelas 2016 년

0

나는 그것이 당신이 요청한 것보다 더 많은 해결 방법이라는 것을 알고 있지만 문제를 해결할 것입니다 (그리고 조각화 또는 헤드 스크래치가 거의 없음).

#step 1
mount /path/to/... /the/new/fs #mount a new filesystem (from NFS? or an external usb disk?)

그리고

#step 2:
cat file* > /the/new/fs/fullfile

또는 압축이 도움이된다고 생각하는 경우 :

#step 2 (alternate):
cat file* | gzip -c - > /the/new/fs/fullfile.gz

그런 다음 마지막으로

#step 3:
rm file*
mv /the/new/fs/fullfile  .   #of fullfile.gz if you compressed it

불행히도 외부 USB 디스크에는 물리적 액세스가 필요하고 nfs에는 추가 하드웨어가 필요하며 아무것도 없습니다. 어쨌든 고마워. =)
돌진

내가 그렇게 될 것이라고 생각 ... 롭 보스의 대답은 당신의 최선의 선택을 보이는 다음이다 (절단 - 동안 - 복사하여 데이터 손실 위험없이 등과 같은 FS 제한을 타격없이 잘)
올리비에 Dulac
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.