디스크에 남은 여유 공간이 각각 10G 인 5 개의 거대한 파일 (file1, file2, .. file5)이 있으며이 모든 파일을 하나로 연결해야합니다. 원본 파일을 유지할 필요는 없으며 마지막 파일 만 보관하십시오.
일반적인 연결은 함께가는 cat
파일을 순서대로 file2
.. file5
:
cat file2 >> file1 ; rm file2
불행히도이 방법은 내가 가지고 있지 않은 최소 10G 여유 공간이 필요합니다. 실제로 복사하지 않고 파일을 연결하는 방법이 있지만 파일 시스템에 어떻게 든 file1이 원래 file1 끝에서 끝나지 않고 file2 시작에서 계속된다고 알려주십시오.
추신. 중요한 경우 파일 시스템은 ext4입니다.
답변
AFAIK (불행히도) 처음부터 파일을 자르는 것은 불가능합니다 (표준 툴에서는 가능하지만 syscall 레벨 은 여기를 참조하십시오 ). 그러나 약간의 복잡성을 추가하면 일반 잘림을 사용할 수 있습니다 (드문 파일과 함께). 사이에 모든 데이터를 쓰지 않고도 대상 파일의 끝에 쓸 수 있습니다.
먼저 두 파일이 모두 정확히 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
블록 크기 결과 파일은 조각의 악몽이 될 것입니다.
답변
프로그램이 여러 파일을 처리 할 수없는 경우 파일을 하나의 파일로 묶는 대신 명명 된 파이프를 사용하여 단일 파일을 시뮬레이션 할 수 있습니다.
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로 균등하게 나눠야합니다. 그렇지 않으면 일부 데이터가 손실됩니다. 그렇다면 괜찮습니다. 나는 그가 또한 아래에 언급 한 것을 본다.
답변
사용 가능한 여유 공간만큼 많은 데이터를 묶음으로 복사하는 것을 작성해야합니다. 다음과 같이 작동합니다.
- 읽기 전에 올바른 위치를 찾아서
file2
사용하여 데이터 블록을pread()
읽습니다. - 에 블록을 추가하십시오
file1
. fcntl(F_FREESP)
에서 공간을 할당 해제하는 데 사용 합니다file2
.- 반복
답변
나는 그것이 당신이 요청한 것보다 더 많은 해결 방법이라는 것을 알고 있지만 문제를 해결할 것입니다 (그리고 조각화 또는 헤드 스크래치가 거의 없음).
#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