gzip 파일의 내부 압축 풀기

gzip 파일의 내부 압축 풀기

gzip으로 압축된 대용량 파일(420GB)이 있고 압축을 풀고 싶지만 하드 드라이브에 전체 압축 파일과 해당 내용을 저장할 공간이 없습니다.

"삭제하는 동안" 압축을 풀 수 있는 방법이 있나요?

도움이 된다면 gzip -l은 내부에 파일이 하나만 있다고 말합니다(tar 파일이므로 어떻게든 분리해야 합니다).

미리 감사드립니다!

답변1

"삭제하는 동안" 압축을 풀 수 있는 방법이 있나요?

그것이 당신이 요구하는 전부입니다. 그러나 이것은 당신이 정말로 원하는 것이 아닐 수도 있습니다. 자신의 책임하에 사용하십시오.

420GB 파일이 스파스 파일 및 홀 펀칭을 지원하는 파일 시스템에 저장된 경우(예 ext4: xfs는 지원되지 않음 ntfs) 파일 읽기를 사용하고 읽기 블록을 해제할 수 있습니다 fallocate --punch-hole. 그러나 어떤 이유로든 프로세스가 취소되면 절반은 삭제되고 절반은 압축되지 않은 파일만 남게 되므로 복구가 불가능할 수 있습니다. 먼저 소스 파일의 또 다른 복사본을 만들지 않고는 이 작업을 시도하지 마세요.

매우 대략적인 개념 증명:

# dd if=/dev/urandom bs=1M count=6000 | pigz --fast > urandom.img.gz
6000+0 records in
6000+0 records out
6291456000 bytes (6.3 GB, 5.9 GiB) copied, 52.2806 s, 120 MB/s
# df -h urandom.img.gz 
Filesystem      Size  Used Avail Use% Mounted on
tmpfs           7.9G  6.0G  2.0G  76% /dev/shm

urandom.img.gz파일은 사용 가능한 공간의 76%를 차지하므로 직접 압축을 풀 수 없습니다. md5sum나중에 확인할 수 있도록 압축되지 않은 결과를 우리에게 파이프하십시오 .

# gunzip < urandom.img.gz | md5sum
bc5ed6284fd2d2161296363edaea5a6d  -

펀칭 중 압축 풀기: (매우 조잡하며 오류 검사가 없습니다.)

total=$(stat --format='%s' urandom.img.gz) # bytes
total=$((1+$total/1024/1024)) # MiB
for ((offset=0; offset < $total; offset++))
do
    # read block
    dd bs=1M skip=$offset count=1 if=urandom.img.gz 2> /dev/null
    # delete (punch-hole) blocks we read
    fallocate --punch-hole --offset="$offset"MiB --length=1MiB urandom.img.gz
done | gunzip > urandom.img

결과:

# ls -alh *
-rw-r--r-- 1 root root 5.9G Jan 31 15:14 urandom.img
-rw-r--r-- 1 root root 5.9G Jan 31 15:14 urandom.img.gz
# du -hcs *
5.9G    urandom.img
0       urandom.img.gz
5.9G    total
# md5sum urandom.img
bc5ed6284fd2d2161296363edaea5a6d  urandom.img

체크섬이 일치하고 압축을 풀면 소스 파일 크기가 6GB에서 0으로 줄어듭니다.

하지만 잘못될 수 있는 일이 많이 있습니다... 아예 하지 않는 것이 낫습니다. 꼭 해야 한다면 적어도 보다 강력한 오류 검사를 수행하는 프로그램을 사용하십시오. 위의 루프는 데이터가 삭제되기 전에 읽고 처리되었음을 전혀 보장하지 않습니다. dd어떤 gunzip이유로든 오류가 반환 되면 fallocate기꺼이 그것을 버릴 것입니다... 따라서 이 접근 방식을 사용해야 한다면 더 건전한 read-and-eat프로그램을 작성하는 것이 좋습니다.

답변2

두 번째 하드 드라이브가 있는 경우 압축된 아카이브를 그곳으로 옮긴 다음 압축을 풀고 원하는 위치에 아카이브를 해제할 수 있습니다.

$ mv archive.gz /mnt/somedrive/
$ cd /where/it/should/go
$ tar xvzf /mnt/somedrive/archive.gz

답변3

그것은 당신이 그것으로 무엇을 하고 싶은지에 달려 있습니다.

.tar.gz 파일인 경우 먼저 .tar.gz로 압축을 풀지 않고도 tar 내용을 볼 수 있습니다 tar --list -zf /path/to/file.

그런 다음 tgz에서 특정 파일만 원하는 경우에는 tar -xzvf /path/to/file relative/path/to/files/inside/tar평소처럼 변경 대상 디렉터리를 사용할 수 있습니다 -C.

이는 .tar.gz가 실제로 gz로 압축된 .tar 파일임에도 불구하고 tar가 플래그를 전달하여 내장된 파일을 사용하도록 선택할 만큼 일반적이기 때문에 좋지 않습니다 -z. 이 플래그는 xz 또는 lz4가 아닌 gzip에만 적용됩니다(bzip2도 가능할지 잘 모르겠습니다).

추가 답변으로, .gz 내부의 파일이 tar가 아닌 경우 항상 출력을 페이저(예: less)로 파이프하여 메모리에 저장할 수 있습니다.gzcat /path/to/file | less

관련 정보