多数のzipアーカイブがあり、それぞれに多数のzipアーカイブが含まれています。このzipアーカイブとその子zipアーカイブに含まれるすべてのファイルを再帰的に抽出する最良の方法は何ですか?
多数のzipアーカイブがあり、それぞれに多数のzipアーカイブが含まれています。このzipアーカイブとその子zipアーカイブに含まれるすべてのファイルを再帰的に抽出する最良の方法は何ですか?
回答:
これにより、すべてのzipファイルが現在のディレクトリに抽出され、それらに含まれるzipファイルは除外されます。
find . -type f -name '*.zip' -exec unzip -- '{}' -x '*.zip' \;
これによりコンテンツが現在のディレクトリに抽出されますが、コンテンツにサブディレクトリが含まれている可能性があるため、すべてのファイルがこのディレクトリに厳密に格納されるわけではありません。
実際にすべてのファイルを厳密に現在のディレクトリに配置したい場合は、次を実行できます。
find . -type f -mindepth 2 -exec mv -- '{}' . \;
注:異なるディレクトリに同じ名前のファイルが2つある場合、ファイルが上書きされます。
すべての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 [ "
見つける。-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
私が理解している限り、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
unzip
UNIXの方法では、すべてのツールですべてのクレイジーな特殊なケースを処理するのではなく、1つのことを行い、それを適切に行うためです。したがって、シェルを使用する必要があります(これは「物事を結び付ける」という仕事をうまく行います)。これはプログラミングの質問になります。また、StackOverflowでプログラミングに関するすべての質問に回答しているので、ここで:Unixコマンドラインからディレクトリとそのサブディレクトリにアーカイブを再帰的に解凍するにはどうすればよいですか?
この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($_);
}
最も簡単な方法は、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
ここでの振る舞いは、私が言うようにunzipと大きく異なりません。再帰的にZIPファイルも抽出しません。
zipファイル内のzipファイルの自動解凍には注意が必要です。
http://research.swtch.com/2010/03/zip-files-all-way-down.html
出力としてzipファイルを生成するzipファイルを作成すること、出力としてzipファイルを生成することなどが可能です。つまり、プログラムを「解凍」する固定ointであるzipファイルを作成できます。
また、「爆発」するzipファイルを作っている人々を思い出すようです。つまり、非常に小さなzipファイルは数ギガバイトの出力に解凍されます。これは、圧縮方法の一面です。
たぶんこれが役立つでしょう(私のために働いた):
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
}
Gilesのような2010年のソリューションが必要でしたが、最上位のディレクトリにすべてを解凍するのではなく、フォルダー構造を保持する必要がありました。3行追加/変更した彼の見解を以下に示します。
#!/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