약 200만 개(60GiB)의 작은 gzip 파일이 있고 모든 파일의 압축되지 않은 버전이 포함된 압축 아카이브를 만들고 싶습니다. 안타깝게도 여유 디스크 공간이 약 70GiB밖에 없기 때문에 압축을 모두 풀고 압축된 아카이브를 생성할 수 없습니다. 즉, GNU tar 에 tar --file-filter="zcat" zcf file.tar.gz directory
그러한 명령줄 스위치가 없다면 어떻게 동등한 작업을 수행할 수 있습니까?--file-filter
답변1
한 가지 옵션은 다음과 같습니다.avfs
(이것은 GNU 시스템을 가정합니다):
mkdir ~/AVFS &&
avfsd ~/AVFS &&
cd ~/AVFS/where/your/gz/files/are/ &&
find . -name '*.gz' -type f -printf '%p#\0' |
tar --null -T - --transform='s/.gz#$//' -cf - | pigz > /dest/file.tar.gz
답변2
불쾌한 파일 이름의 경우 이는 취약하다는 점에 유의하세요.
dir_with_small_files=/home/john/files
tmpdir=/tmp/ul/dst
tarfile=/tmp/ul.tar
mkfifo "${tarfile}"
gzip <"${tarfile}" >"${tarfile}.gz" &
find "$dir_with_small_files" -type f | \
while read src; do
dstdir="${tmpdir}/$(dirname $src)"
dst="$(basename $src .gz)"
mkdir -p "$dstdir"
gunzip <"$src" >"${dstdir}/${dst}"
# rm "$src" # uncomment to remove the original files
echo "${dstdir}/${dst}"
done | \
cpio --create --format=ustar -v --quiet 2>&1 >"${tarfile}" | \
while read x; do
rm "$x"
done
# clean-up
rm "$tarfile"
rm -r "$tmpdir"
아래의 파일은 일시적으로 압축이 풀려 바로 $tmpdir
그때로 전달되며, 아카이브에 추가되는 즉시 삭제됩니다.cpio
답변3
지금까지 시도한 내용은 다음과 같습니다. 작동하는 것처럼 보이지만 PyPy를 사용하더라도 매우 느립니다.
#!/usr/bin/python
import tarfile
import os
import gzip
import sys
import cStringIO
tar = tarfile.open("/dev/stdout", "w|")
for name in sys.stdin:
name = name[:-1] # remove the trailing newline
try:
f = gzip.open(name)
b = f.read()
f.close()
except IOError:
f = open(name)
b = f.read()
f.close()
# the [2:] there is to remove ./ from "find" output
ti = tarfile.TarInfo(name[2:])
ti.size = len(b)
io = cStringIO.StringIO(b)
tar.addfile(ti, io)
tar.close()
용법:find . | script.py | gzip > file.tar.gz