나는 많은 zip 아카이브를 가지고 있으며 각 zip 아카이브에는 여러 개의 zip 아카이브가 포함되어 있습니다. 이 zip 아카이브와 해당 하위 zip 아카이브(그 자체로는 zip 아카이브가 아님)에 포함된 모든 파일을 재귀적으로 추출하는 가장 좋은 방법은 무엇입니까?
답변1
그러면 포함된 zip 파일을 제외하고 모든 zip 파일이 현재 디렉터리로 추출됩니다.
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
답변2
내가 이해한 바에 따르면 귀하의 zip 아카이브 자체에는 zip 아카이브가 포함되어 있으며 중첩된 zip의 압축을 풀 때 중첩된 zip의 압축을 풀기를 원합니다.
이것은 현재 디렉터리와 하위 디렉터리에 있는 모든 zip의 압축을 반복적으로 풀고, 압축을 푼 후 각 zip 파일을 제거하고, zip 파일이 있는 한 계속해서 압축을 푸는 bash 4 스크립트입니다. 하위 디렉터리의 zip 파일은 해당 하위 디렉터리를 기준으로 추출됩니다. 경고: 테스트되지 않았습니다. 원본 파일을 백업하거나 시도하기 전에 rm
zip 파일을 이동하여 교체하세요.디렉토리 트리 외부.
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
답변3
이 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($_);
}
답변4
zip 파일 내에서 zip 파일의 압축을 자동으로 풀 때 주의하세요.
http://research.swtch.com/2010/03/zip-files-all-way-down.html
zip 파일을 출력으로 생성하는 zip 파일을 생성하고, 출력으로 zip 파일을 생성하는 등의 작업을 수행할 수 있습니다. 즉, "unzip" 프로그램의 고정 지점인 zip 파일을 만들 수 있습니다.
또한 사람들이 "폭발"할 zip 파일을 만든 것을 기억하는 것 같습니다. 즉, 아주 작은 zip 파일은 압축을 풀어 수 기가바이트의 출력으로 만듭니다. 이것이 압축 방법의 한 측면입니다.