중첩 된 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.