.zip に親ディレクトリが含まれているかどうかを事前に確認する方法

.zip に親ディレクトリが含まれているかどうかを事前に確認する方法

何度か、 があるとします。a.zipこれはそれ自体に解凍されますa/*

ただし、多くの場合、すべての内容が現在のディレクトリに漏れてしまう zip ファイルがあります。この場合、手動でディレクトリを作成しa、そこに解凍する必要があります。

しかし、ポリシーとして常にディレクトリを作成し、zip が最初の種類であることが判明した場合、構造は次のようになり、a/a/*理想的ではありません。

上記で説明した 2 つのタイプのうち、タイプに関係なくa.zip解凍する方法はありますか?a/*

答え1

これを試して:

archive="archive.zip"
has_parent=$(unzip -l "$archive" | tail -n+4 | head -n-2 | awk '{split($NF,a,"/");print a[1]}' | sort -u | wc -l)
if test "$has_parent" -eq 1; then
  unzip $archive
else
  dir="./$(basename ${archive%%.zip})"
  mkdir "$dir"
  unzip -d "$dir" $archive
fi

使用する場合、次のように行zipinfoを絞ります$has_parent

has_parent=$(zipinfo -1 "$archive" | awk '{split($NF,a,"/");print a[1]}' | sort -u | wc -l)

アイデアはシンプルです。アーカイブのルート レベルに複数のファイルがある場合、解凍すると現在のディレクトリが破壊されるのは明らかです。そのため、事前に親ディレクトリを作成し、そこにファイルを解凍する必要があります。そうでない場合、アーカイブ内のすべてのファイルの親が同じであれば、現在のディレクトリで解凍しても問題ありません。

答え2

zipinfo表示、zip コンテンツに使用します。

$ zipinfo -1 a.zip

ただし、自動化の回答を探している場合、これはおそらく質問への回答にはなりません。

編集:出力の各行にスラッシュ文字があるかどうかをチェックすることができますzipinfo。スラッシュ文字がない行があれば、その行が zip ファイルのルートにあることがわかります。

残念ながら、これをどうやって実行すればいいのか、すぐには思いつきません。うまくいくかどうかはわかりませんが、テストされていないコマンドを次に示します。

$ MKROOT=0
$ for X in $(zipinfo -1 a.zip); do $(echo "${X}" | grep "/"); if test "$?" -gt "0"; then MKROOT=1; fi; done
$ if test "${MKROOT}" -gt "0"; then mkdir "a"; cd "a"; unzip "../a.zip"; else unzip "a.zip"; fi

編集:Mark Perryman の提案の方がおそらく良いでしょう。私のコマンドはファイルがサブフォルダーに含まれているかどうかをチェックしますが、すべてが同じルートフォルダーの下にあるかどうかはチェックしないことに気づきました。

関連情報