多数の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
私が理解している限り、Zipアーカイブを含むZipアーカイブがあり、ネストされたzipが解凍されるたびに解凍したいと考えています。
次のbash 4スクリプトは、現在のディレクトリとそのサブディレクトリ内のすべてのzipを再帰的に解凍し、解凍後に各Zipファイルを削除し、Zipファイルがある限り続行します。サブディレクトリ内のZipファイルは、そのサブディレクトリを基準にして抽出されます。警告:テストされていません。試す前に元のファイルのバックアップを作成するか、Zipファイルディレクトリツリーの外を移動してrm
を置き換えてください。
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
行をsetopt nullglob
に置き換えると、スクリプトはzshでも機能します。
これがポータブル版です。 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コマンドラインから再帰的に解凍するにはどうすればよいですか?
最も簡単な方法は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
(これを使用する前に、Zipファイルを含む目的のディレクトリにcd
する必要があります)。
この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($_);
}
これをチェックアウトJavaベースのユーティリティ nzip ネストされたZipファイル用。ネストされたzipの抽出と圧縮は、次のコマンドを使用して簡単に実行できます。
Java -jar nzip.jar -c list -s readme.Zip
Java -jar nzip.jar -c extract -s "C:\ project\readme.Zip" -t readme
Java -jar nzip.jar -c compress -s readme -t "C:\ project\readme.Zip"
PS。私は作者であり、バグがあればすぐに修正させていただきます。
2010年からGilesのようなソリューションが必要でしたが、すべてを最上位ディレクトリに解凍せずにフォルダー構造を維持する必要がありました。ここに彼の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
Zipファイル内のZipファイルを自動的に解凍するように注意する必要があります。
http://research.swtch.com/2010/03/Zip-files-all-way-down.html
出力としてZipファイルを生成するZipファイルを作成したり、出力としてZipファイルを生成したりすることなどが可能です。つまり、プログラムを「解凍」することで固定された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
}