중첩 된 zip 파일 추출


15

수많은 zip 아카이브가 있으며 각 아카이브에는 여러 개의 zip 아카이브가 있습니다. 이 zip 아카이브와 하위 zip 아카이브에 포함 된 모든 파일을 zip 아카이브 자체가 아닌 재귀 적으로 추출하는 가장 좋은 방법은 무엇입니까?


zip 파일이 아닌 것을 추출한다는 것은 무슨 의미입니까? 다른 장소로 복사하고 싶습니까?
— phunehehe

귀하의 요구 사항이 명확하지 않습니다. 나는 Shawn J. Goff 와 똑같이 가능성에 대한 나의 해석을 발견 합니다. 당신은 명확히 할 수 있습니까?
— Gilles 'SO- 악마 중지'11

@Gilles : 죄송합니다. 조금 불분명했습니다. 나는 그것을 조금 바꿨다.
— oadams

답변을 게시하려고했지만 의견으로 표시되어야한다고 생각합니다. 중첩 된 아카이브 는 필요한 공간을 늘 립니다 ! 아마도 gzip뿐만 아니라 Zip 파일 형식을 의미 할 것입니다. 모든 zip 파일은 이미 압축되어 다시 압축되어 더 많은 오버 헤드를 생성하여 필요한 공간을 효과적으로 증가시킵니다.
— polemon

네, 안 했어요 : P. 불행히도 나는이 기묘한 방식으로 파일을 배포합니다.
— oadams

답변:


13

그러면 압축 파일에 포함 된 압축 파일을 제외한 모든 압축 파일이 현재 디렉토리로 추출됩니다.

find . -type f -name '*.zip' -exec unzip -- '{}' -x '*.zip' \;

현재 디렉토리로 컨텐츠를 추출하지만 컨텐츠에 서브 디렉토리가 포함될 수 있으므로 모든 파일이이 디렉토리에 엄격하게 들어가지는 않습니다.

실제로 현재 디렉토리에있는 모든 파일을 원한다면 다음을 실행할 수 있습니다.

find . -type f -mindepth 2 -exec mv -- '{}' . \;

참고 : 다른 디렉토리에 동일한 이름을 가진 두 개가있는 경우 파일이 손상됩니다.

모든 zip 파일과 그 안에 포함 된 zip을 재귀 적으로 추출하려면 다음은 현재 디렉토리의 모든 zip 파일과 그 안에 포함 된 모든 zip을 현재 디렉토리로 추출합니다.

while [ "`find . -type f -name '*.zip' | wc -l`" -gt 0 ]
do
    find . -type f -name "*.zip" -exec unzip -- '{}' \; -exec rm -- '{}' \;
done

이 while 루프는 윤리적 인 해킹 경쟁에서 많은 도움을 주었으며, 31337 레벨의 중첩 된 zip 파일을 준비했습니다. 감사합니다!
— 오줌

2
: 당신은 내가 중첩 된 귀, 전쟁, jar 파일에서 반복적으로 추출 내용에 사용이 변형 것 같아서 gist.github.com/tyrcho/479c18795d997c201e53 주요 차이는 각 아카이브에 대한 중첩 된 폴더를 생성입니다. while [ "찾기 . -type f -name '*.? ar'| wc -l" -gt 0 ]; do find -type f -name "*.?ar" -exec mkdir -p '{}.dir' \; -exec unzip -d '{}.dir' -- '../{}' \; -exec rm -- '{}' \;; done
— Michel Daviot 2012 년

4

내가 아는 한, 당신은 그 자체로 압축 아카이브를 포함하는 압축 아카이브를 가지고 있으며 압축이 풀릴 때마다 중첩 된 압축을 풀고 싶습니다.

다음은 현재 디렉토리와 하위 디렉토리의 모든 zip을 재귀 적으로 압축 해제하고 압축을 푼 후 각 zip 파일을 제거하고 zip 파일이있는 한 계속 진행되는 bash 4 스크립트입니다. 서브 디렉토리의 zip 파일은 해당 서브 디렉토리를 기준으로 추출됩니다. 경고 : 테스트를 거치지 않은 상태에서 원본 파일을 백업하거나 백업하기 전에 rmzip 파일을 디렉토리 트리 외부 로 이동하여 바꾸십시오 .

shopt -s globstar nullglob
while set -- **/*.zip; [ $# -ge 1 ] do
  for z; do
    ( cd -- "$(dirname "$z")" &&
      z=${z##*/} &&
      unzip -- "$z" &&
      rm -- "$z"
    )
  done
done

shopt줄을로 바꾸면 스크립트는 zsh에서도 작동 setopt nullglob합니다.

휴대용에 해당합니다. 종료 조건은 find파일을 찾았는지 여부를 나타내는 상태를 자발적으로 반환하지 않기 때문에 약간 복잡 합니다. 경고 : 위와 같이.

while [ -n "$(find . -type f -name '*.zip' -exec sh -c '
    cd "${z%/*}" &&
    z=${z##*/} &&
    unzip -- "$z" 1>&2 &&
    rm -- "$z" &&
    echo 1
')" ]; do :; done

1

unzip유닉스 방식은 한 가지 일을하고 잘하는 것이기 때문에 모든 도구에서 모든 미친 특수 사례를 처리하지 않기 때문에이 작업을 수행하지 않습니다. 따라서 쉘을 사용해야합니다 ( "함께 묶는"작업을 잘 수행함). 이것은 프로그래밍 문제가되며 StackOverflow에서 가능한 모든 프로그래밍 질문에 대한 답을 얻었으므로 여기 에서 디렉토리와 하위 디렉토리의 아카이브를 Unix 명령 줄에서 어떻게 재귀 적으로 압축 해제합니까?


1
나는 "쉘을 사용하여"프로그래밍 문제라고 부르지 않을 것이며, "쉘 스크립팅"은 FAQ에 주제로 나열되어 있습니다.
— Michael Mrozek

나는 그것이 전혀 주제가 아닌 것을 암시하는 것이 아니며, 왜 그것이 OverOver에서 주제에 있는지를 정당화하고 싶었습니다.
— 토마스 테멜

1

이 perl 스크립트는 각 .zip 파일을 자체 하위 디렉토리로 추출합니다. 중첩 된 zip 파일을 처리하려면 스크립트를 두 번 이상 실행하십시오. 추출 후 .zip 파일은 삭제하지 않지만 unlink () 호출을 추가하여 해당 변경을 수행 할 수 있습니다.

#!/usr/bin/perl -w

# This script unzips all .zip files it finds in the current directory
# and all subdirectories.  Contents are extracted into a subdirectory
# named after the zip file (eg. a.zip is extracted into a/).
# Run the script multiple times until all nested zip files are
# extracted.  This is public domain software.

use strict;
use Cwd;

sub process_zip {
    my $file = shift || die;
    (my $dir = $file) =~ s,/[^/]+$,,;
    (my $bare_file = $file);
    $bare_file =~ s,.*/,,;
    my $file_nopath = $bare_file;
    $bare_file =~ s,\.zip$,,;
    my $old_dir = getcwd();
    chdir($dir) or die "Could not chdir from '$old_dir' to '$dir': $!";
    if (-d $bare_file) {
        chdir($old_dir);
        # assume zip already extracted
        return;
    }
    mkdir($bare_file);
    chdir($bare_file);
    system("unzip '../$file_nopath'");
    chdir($old_dir);
}

my $cmd = "find . -name '*.zip'";
open(my $fh, "$cmd |") or die "Error running '$cmd': $!";
while(<$fh>) {
    chomp;
    process_zip($_);
}

1

가장 쉬운 방법은 atool을 사용하는 것입니다 : http://www.nongnu.org/atool/ zip, unzip, tar, rar 등의 프로그램을 사용하여 아카이브를 추출하는 매우 좋은 스크립트입니다.

사용 atool -x package_name.zip모두 압축을 해제하거나 당신이 많은 zip 파일과 디렉토리에 사용하려는 경우 간단한 사용 for루프 :

for f in *; do atool -x $f; fi( cd이를 사용하기 전에 zip 파일이있는 원하는 디렉토리 로 들어가야합니다).


atool의 동작은 압축 해제와 크게 다르지 않습니다. ZIP 파일도 재귀 적으로 추출하지 않습니다.
— 토마스 테멜

@Thomas Themel : ZIP 파일을 재귀 적으로 추출하지 않습니까? tar.gz를 deb 파일에서 추출 할 수는 있지만 중첩 된 zip 아카이브로 테스트 할 시간이 없습니다 : \

0

zip 파일 내에서 zip 파일의 압축을 자동으로 풀 때주의해야합니다.

http://research.swtch.com/2010/03/zip-files-all-way-down.html

zip 파일을 출력으로 생성하고 zip 파일을 출력 등을 생성하는 등을 수행하는 zip 파일을 생성 할 수 있습니다. 즉, 프로그램의 "unzip"이라는 고정 된 연고 인 zip 파일을 만들 수 있습니다.

또한, "폭발"하는 zip 파일을 만드는 사람들을 기억하는 것 같습니다. 매우 작은 zip 파일은 수 기가 바이트의 출력으로 압축을 풀 것입니다. 이것은 압축 방법의 한 측면입니다.


0

어쩌면 이것이 도움이 될 것입니다 (나에게 효과적).

function unzipAll(){

# find and count archives
archLst=`find . -type f -name "*.*ar"`
archLstSize=`echo $archLst| awk 'END{print NF}'`

# while archives exists do extract loop
while [ "$archLstSize" -gt 0 ]; do

# extract and remove all archives (found on single iteration)
for x in $archLst; do 
mv "${x}" "${x}_";
unzip "${x}_" -d "${x}" && rm "${x}_"; 
done; #EO for

# find and count archives
archLst=`find . -type f -name "*.*ar"`
archLstSize=`echo $archLst| awk 'END{print NF}'`

done #EO while

}

0

2010 년부터 Giles '와 같은 솔루션이 필요했지만 모든 것을 최상위 디렉토리에 압축 해제하지 않고 폴더 구조를 보존해야했습니다. 다음은 세 줄을 추가 / 변경 한 그의 테이크입니다.

#!/bin/bash
shopt -s globstar nullglob
while set -- **/*.zip; [ $# -ge 1 ]
do
    for z
    do
        ( cd -- "$(dirname "$z")" &&
            z=${z##*/} &&
            cp -- "$z" "$z".bak &&
            mkdir -- "$z"dir &&
            unzip -- "$z" -d "$z"dir &&
            rm -- "$z"
        )
    done
done

0

중첩 된 zip 파일에 대해서는 이 Java 기반 유틸리티 nzip 을 확인하십시오. 다음 명령을 사용하여 중첩 된 zip 추출 및 압축을 쉽게 수행 할 수 있습니다.

java -jar nzip.jar -c 목록 -s readme.zip

java -jar nzip.jar -c 추출 -s "C : \ project \ readme.zip"-t readme

java -jar nzip.jar -c 압축 -s readme -t "C : \ project \ readme.zip"

추신. 저는 저자이며 버그를 신속하게 해결해 드리겠습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.