여러 압축 파일을 하나의 아카이브로 병합하는 방법은 무엇입니까?

여러 압축 파일을 하나의 아카이브로 병합하는 방법은 무엇입니까?

거의 동일한 파일이 수백 개 있습니다 .tar.xz(매일 데이터베이스 덤프이고 데이터베이스가 느리게 변경됩니다).

나는 압축되지 않은 파일의 유사성으로 인해 압축이 잘 될 것이라고 믿습니다. 소규모 테스트에 따르면 이러한 압축되지 않은 파일을 원하는 만큼 압축하면 그 중 하나보다 약간 더 큰 아카이브가 생성되는 것으로 나타났습니다.

내 문제는 압축되지 않은 모든 파일이 수 테라바이트(압축 비율은 약 25:1)가 되며 작업 공간으로 사용할 디스크 공간이 그렇게 많지 않다는 것입니다.

개별 압축 파일을 한 번에 하나씩 처리하여 단일 아카이브에 추가하고 함께 압축하는 이점을 유지할 수 있는 방법이 있습니까?

답변1

tar 파일은 스트리밍 형식이므로 cat두 개를 함께 사용하면 거의 정확한 결과를 얻을 수 있습니다. 이 작업을 수행하기 위해 디스크에 추출할 필요가 전혀 없습니다. 파일의 압축을 풀고 함께 연결한 다음 스트림을 다시 압축할 수만 있습니다.

xzcat *.tar.xz | xz -c > combined.tar.xz

combined.tar.xz어셈블리 타르볼의 모든 파일이 압축된 타르볼이 되며 약간만 손상되었습니다. 추출하려면 다음을 사용해야합니다.--ignore-zeros옵션(GNU에서 tar) 아카이브에는 "파일 끝" 표시가 있기 때문에 결과 중간에 나타납니다. 하지만 그 외에는 모든 것이 잘 작동할 것입니다.

GNU tar도 지원합니다--concatenate결합된 아카이브를 생성하기 위한 패턴입니다. 위와 동일한 제한 사항이 있습니다. 압축을 풀려면 이를 사용해야 합니다 --ignore-zeros. 그러나 압축된 아카이브에서는 작동하지 않습니다. 프로세스 대체를 사용하여 작동하도록 속이는 무언가를 만들 수 있지만 이는 번거롭고 훨씬 더 취약합니다.

일부 파일이 다른 tar 파일에 여러 번 나타나는 경우에는 작동하지 않지만 어쨌든 문제가 발생합니다. 그렇지 않으면 원하는 것을 얻을 수 있습니다. 출력을 파이핑하는 것은 출력을 압축하는 방법 xz입니다 .tar


특정 tar구현만을 위한 아카이브가 목적에 충분하지 않은 경우 r다음을 아카이브에 추가할 수 있습니다.

tar cJf combined.tar.xz dummy-file
for x in db-*.tar.xz
do
    mkdir tmp
    pushd tmp
    tar xJf "../$x"
    tar rJf ../combined.tar.xz .
    popd
    rm -r tmp
done

한 번에 하나의 아카이브만 추출할 수 있으므로 작업 공간은 단일 아카이브의 콘텐츠 크기로 제한됩니다. 마치 최종 아카이브를 한번에 만드는 것처럼 압축이 스트리밍 되기 때문에 이전과 동일하게 됩니다. 과도하게 압축을 풀고 다시 압축하는 작업을 많이 수행하여 버전보다 속도가 느려지지만 cat결과 아카이브는 특별한 지원 없이 어디에서나 작동합니다.

특정 요구 사항에 따라 압축되지 않은 tar 파일 자체를 아카이브에 추가하는 것만으로도 충분할 수 있습니다. 단일 파일의 내용을 (거의) 완전히 압축하고 파일별 압축 오버헤드를 줄입니다. 이것은 다음과 같습니다:

tar cJf combined.tar.xz dummy-file
for x in db-*.tar.xz
do
    xz -dk "$x"
    tar rJf combined.tar.xz "${x%.xz}"
    rm -f "${x%.xz}"
done

스트림의 추가 tar 헤더로 인해 최종 압축 크기 측면에서 효율성이 약간 떨어지지만 모든 파일을 추출하고 파일에 다시 추가하는 데 시간이 절약됩니다. 결국 combined.tar.xz많은 (압축되지 않은) db-*.tar파일이 생성됩니다.

관련 정보