一般的な状況は、他のタスクを含むディレクトリにzipファイルを含めることです。
me@work ~/my_working_folder $ ls
downloaded.zip workfile1 workfile2 workfile3
解凍したいのですが、downloaded.zip
混乱を招くのか、それとも自分のディレクトリを素敵に作成するのかわかりません。私が取り組んでいる解決策は、一時フォルダを作成してそのフォルダに解凍することです。
me@work ~/my_working_folder $ mkdir temp && cp downloaded.zip temp && cd temp
me@work ~/my_working_folder/temp $ ls
downloaded.zip
me@work ~/my_working_folder/temp $ unzip downloaded.zip
Archive: downloaded.zip
creating: nice_folder/
これにより、my_working_folder
zipファイルが大量のコンテンツで埋められるのを防ぎます。
私の質問は次のとおりです解凍する前にzipファイルにフォルダが1つしか含まれていないことを確認するより良い方法はありますか?
答え1
わかったできる無条件にサブディレクトリに抽出し、単一のエントリのみが含まれる場合は削除してください。
しかし、なぜ行くのですか?健全でシンプルなソリューション(頼るイルカチョ)、いつから使用できますかawk
? :)
sunzip ()
{
if [ $# -ne 1 ] || ! [ -f "$1" ]
then
printf '%s\n' "Expected a filename as the first (and only) argument. Aborting."
return 1
fi
extract_dir="."
# Strip the leading and trailing information about the zip file (leaving
# only the lines with filenames), then check to make sure *all* filenames
# contain a /.
# If any file doesn't contain a / (i.e. is not located in a directory or is
# a directory itself), exit with a failure code to trigger creating a new
# directory for the extraction.
if ! unzip -l "$1" | tail -n +4 | head -n -2 | awk 'BEGIN {lastprefix = ""} {if (match($4, /[^/]+/)) {prefix=substr($4, RSTART, RLENGTH); if (lastprefix != "" && prefix != lastprefix) {exit 1}; lastprefix=prefix}}'
then
extract_dir="${1%.zip}"
fi
unzip -d "$extract_dir" "$1"
}
速くて汚い。 InfoZIP unzip
v6.0に適用されます。追加のパラメータを許可したり、自動的に使用したり、抽出サブディレクトリに別の名前(現在のファイル名で決定)を使用する
など、必要に応じてそれらを調整できます。unzip
zip
ああ、この回避策が最も一般的な2つの場合(1. ZIPファイルにコンテンツを含むディレクトリが含まれている場合、2. ZIPファイルに複数の別々のファイルおよび/またはディレクトリが含まれている場合)は正しく処理されますが、ルートディレクトリが作成されないことを確認しました。 ZIPファイルには複数のディレクトリが含まれていますが、ファイルはありません。サブディレクトリは...
編集する:安定した。スクリプトawk
はZIPファイルに含まれている各パスの最初のコンポーネント(「プレフィックス」)を保存し、以前のプレフィックスとは異なるプレフィックスが検出されるとすぐに中断されます。これは、すべてのコンテンツが同じサブディレクトリに含まれるZIPファイルを無視しながら、複数のファイルと複数のディレクトリ(両方とも名前が異なるため)をキャプチャします。
答え2
抽出する前にアーカイブの内容を確認するのではなく、次のコマンドを使用して抽出することもできます。unar
これは所望の動作を提供する。デフォルトでは、アーカイブに単一の最上位ディレクトリが含まれている場合はそのまま抽出され、unar
それ以外の場合はアーカイブ名のディレクトリを作成してそこから抽出します。このオプションを使用すると、すべての場合にディレクトリを強制的に作成できます-d
。
unar
また、さまざまなアーカイブ形式をサポートするという利点もあります。
答え3
マニュアルで...
[-d ディレクトリ]
ファイルを抽出するオプションのディレクトリです。デフォルトでは、すべてのファイルとサブディレクトリは現在のディレクトリに再作成されます。 -dオプションを使用すると、任意のディレクトリから抽出できます(そのディレクトリへの書き込み権限は常に仮定されます)。このオプションはコマンドラインの末尾に表示される必要はありません。 zipfile指定の前(通常オプションを使用)、zipfile指定の直後、またはファイルと-xオプションの間にも許可できます。オプションとディレクトリは空白なしで接続できますが、これは通常のシェルの動作を抑制する可能性があることに注意してください。特に
-d ~
(チルダ)はUnix Cシェルではユーザーのホームディレクトリ名に展開されますが、現在のディレクトリの文字通りサブディレクトリとして扱わ-d~
れます。~
だから...
unzip -d new_dir zipfile.zip
これにより、new_dirディレクトリが作成され、その中にあるアーカイブが抽出されますので、最初に見ることなく、毎回潜在的な混乱を避けることができます。見てみるのも便利ですman unzip
。マニュアルページの追加ヘルプ。
答え4
デフォルトの解凍を使用する素晴らしいbash oneライナーは次のとおりです。
while read -r line; do (unzip -d "$(basename "$line" .zip)" "$line"); done < <(find . | grep '.zip')
抽出するzipファイルを含むディレクトリでこのコマンドを実行します。
< <
結果をfind . | grep '.zip'
ループに入力しますwhile
。- 返されたファイル名は次のよう
find
に保存されます。line
- この
while
ループはファイル名を繰り返してファイルline
名をdo
- これにより、次のファイル名を使用して
do
ディレクトリが作成されます。basename
$line
- 拡張子は、
.zip
文字列から削除するテキストとして指定されます。 - 拡張子なしでファイル名のみを残します(デフォルト名!)
- 拡張子は、
- 新しいディレクトリの作成に使用
-d
するデフォルト名を引数します。.zip
/folder/archive.zip
すると待ちます/folder/archive/unzipped_file.txt
。- これはWindows / 7zipの「抽出先」オプションと非常によく似ています。
- その後、この変数は
$line
解凍の対象として使用されます。
このライナーは様々なアイテムにも使えますよ!ファイル移動、ファイル圧縮、ファイルコピー...検索が再帰的で、とても便利です!