gzip으로 압축된 tar-ballcompressedArchive.tgz(+100개 파일, +5GB 총)가 있다고 가정해 보겠습니다.
주어진 파일 이름 패턴(예: 접두사 *.jpg)과 일치하는 모든 항목을 제거한 다음 나머지를 gzip:ed tar-ball에 다시 저장하는 가장 빠른 방법은 무엇입니까?
이전 아카이브를 교체하거나 새 아카이브를 생성하는 것 중 가장 빠른 것은 중요하지 않습니다.
답변1
GNU를 사용하면 tar
다음을 수행할 수 있습니다.
pigz -d < file.tgz |
tar --delete --wildcards -f - '*/prefix*.jpg' |
pigz > newfile.tgz
그리고 bsdtar
:
pigz -d < file.tgz |
bsdtar -cf - --exclude='*/prefix*.jpg' @- |
pigz > newfile.tgz
( pigz
다중 스레드 버전입니다 gzip
).
다음과 같이 파일 자체를 덮어쓸 수 있습니다.
{ pigz -d < file.tgz |
tar --delete --wildcards -f - '*/prefix*.jpg' |
pigz &&
perl -e 'truncate STDOUT, tell STDOUT'
} 1<> file.tgz
그러나 이것은 매우 위험합니다. 특히 결과가 원본 파일보다 덜 압축된 경우(이 경우 두 번째 파일은 pigz
첫 번째 파일이 아직 읽지 않은 파일 영역을 덮어쓰게 될 수 있습니다).
답변2
단순한 접근 방식을 과소평가하지 마십시오. 귀하의 목적에 맞게 충분히 빠를 수도 있습니다. 그리고AVFS아카이브에 디렉터리로 액세스합니다.
cd ~/.avfs/path/to/original.tar.gz\#
pax -w -s '/^.*\.jpg$//' | gzip >/path/to/filtered.tar.gz # POSIX
tar -czf /path/to/filtered.tar.gz -s '/^.*\.jpg$//' . # BSD
tar -czf /path/to/filtered.tar.gz --transform '/^.*\.jpg$//' . # GNU
보다 원시적인 도구를 사용하여 먼저 제외된 파일의 파일을 추출한 .jpg
다음 새 아카이브를 만듭니다.
mkdir tmpdir && cd tmpdir
<original.tar.gz gzip -d | pax -r -pe -s '/^.*\.jpg$//'
pax -w . | gzip >filtered.tar.gz
cd .. && rm -rf tmpdir
타르에 다음이 있는 경우 --exclude
:
mkdir tmpdir && cd tmpdir
tar -xzf original.tar.gz --exclude='*.jpg'
tar -czf filtered.tar.gz .
cd .. && rm -rf tmpdir
그러나 루트로 실행하지 않으면 파일 소유권과 스키마가 손상될 수 있습니다. 최상의 결과를 얻으려면 빠른 파일 시스템의 임시 디렉토리인 tmpfs를 사용하십시오(파일 시스템이 충분히 큰 경우).
통과(예: 아카이브 파일 읽기 및 아카이브 파일 쓰기) 역할을 하는 아카이버에 대한 지원은 제한되는 경향이 있습니다.GNU tar는 아카이브에서 구성원을 제거할 수 있습니다.그리고--delete
작업 옵션("이 옵션은 에서 까지의 필터 역할을 할 때 제대로 작동하는 것으로 보고되었습니다 --delete
.") 이것이 최선의 선택일 수 있습니다.tar
stdin
stdout
몇 줄의 Python 코드로 강력한 아카이브 필터를 만들 수 있습니다. 그것은tarfile
라이브러리는 검색할 수 없는 스트림에서 읽고 쓸 수 있으며 Python에서 임의의 코드를 사용하여 필터링, 이름 바꾸기, 수정 등을 수행할 수 있습니다.
#!/usr/bin/python
import re, sys, tarfile
source = tarfile.open(fileobj=sys.stdin, mode='r|*')
dest = tarfile.open(fileobj=sys.stdout, mode='w|gz')
for member in source:
if not (member.isreg() and re.match(r'.*\.jpg\Z', member.name)):
sys.stderr.write(member.name + '\n')
dest.addfile(member, source.extractfile(member))
dest.close()
답변3
Mac OSX에서 tar를 사용하면 다음을 수행할 수 있습니다.
tar -czf b.tgz --exclude '*.jpg' @a.tgz
mv b.tgz a.tgz
답변4
나는 사용한다:
tar -xvf myLarge.gz --exclude "prefix" | tar -czvf myLarge.gz -T -
이는 다음을 수행합니다.
- "를 포함하는 파일을 제외한 모든 파일을 추출합니다.접두사"
- (
-T -
) 나머지 내용을 tar로 파이프하고 myLarge.gz를 다시 압축합니다.