5개의 대용량 파일(파일 1, 파일 2, .. 파일 5)이 각각 약 10G이고 디스크에 남은 여유 공간이 매우 부족하므로 이 모든 파일을 하나로 연결해야 합니다. 원본 파일을 보관할 필요 없이 최종 파일만 보관하면 됩니다.
cat
일반적인 연결은 파일 순서대로 수행됩니다 file2
.. file5
:
cat file2 >> file1 ; rm file2
불행하게도 이 방법을 사용하려면 최소한 10G의 여유 공간이 필요하지만 나에게는 그런 여유 공간이 없습니다. 파일을 실제로 복사하지 않고 연결하는 방법이 있습니까? 하지만 파일 시스템에 file1이 원래 file1이 끝나는 곳에서 끝나지 않고 file2가 시작되는 곳에서 계속된다는 것을 어떻게든 알릴 수 있습니까?
PS 중요한 경우 파일 시스템은 ext4입니다.
답변1
AFAIK 불행하게도 처음부터 파일을 자르는 것은 불가능합니다(표준 도구에서는 해당될 수 있지만 시스템 호출 수준에서는 해당되지 않음).이봐). 그러나 약간의 복잡성이 추가되면서 일반 잘림(스파스 파일 사용)을 사용할 수 있습니다. 사이에 모든 데이터를 쓰지 않고 대상 파일의 끝에 쓸 수 있습니다.
먼저 이 두 파일의 크기가 정확히 5GiB(5120MiB)이고 한 번에 100MiB를 이동한다고 가정해 보겠습니다. 다음을 포함하는 루프를 실행합니다.
- 원본 파일의 끝부터 대상 파일의 끝까지 블록을 복사합니다(소모되는 디스크 공간 증가).
소스 파일 일부 자르기(디스크 공간 확보)
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
결과 파일은 조각화의 악몽이 됩니다.
답변2
프로그램이 여러 파일을 처리할 수 없는 경우 파일을 단일 파일로 병합하는 대신 명명된 파이프를 사용하여 단일 파일을 에뮬레이트할 수 있습니다.
mkfifo /tmp/file
cat file* >/tmp/file &
blahblah /tmp/file
rm /tmp/file
Hauke가 제안한 대로 losstup/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로 나눌 수 있어야 합니다. 그렇지 않으면 일부 데이터가 손실됩니다. 그렇다면 가셔도 좋습니다. 나는 그가 아래에서도 이것을 지적하는 것을 봅니다.
답변3
최대로 가지고 있는 여유 공간만큼의 데이터를 복사하려면 무언가를 작성해야 합니다. 다음과 같이 작동해야 합니다:
- 여기에서 데이터 덩어리를 읽습니다
file2
(pread()
올바른 위치를 읽기 전에 통과 조회 사용). - 블록을 에 추가합니다
file1
. fcntl(F_FREESP)
공간 할당을 해제하는 데 사용됩니다file2
.- 반복하다
답변4
나는 이것이 귀하가 요청한 것보다 더 많은 해결 방법이라는 것을 알고 있지만 문제를 해결할 것입니다(조각화나 번거로움이 거의 또는 전혀 없음).
#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