Как заранее узнать, есть ли внутри .zip-архива родительский каталог

Как заранее узнать, есть ли внутри .zip-архива родительский каталог

В некоторых случаях, скажем, у меня есть a.zip, который распаковывается сам в a/*себя.

Однако часто встречаются zip-файлы, которые выливают все свое содержимое в текущий каталог. Это требует от меня вручную создать директорию aи распаковать в нее.

Но если в качестве политики я всегда создаю каталог, а zip-архив оказывается первого типа, моя структура выглядит так, a/a/*что не является идеальным.

Есть ли способ распаковать архив 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

Редактировать:Предложение Марка Перримана, вероятно, лучше. Я только что понял, что моя команда проверяет, содержатся ли файлы в подпапках, но не проверяет, содержатся ли все они в одной и той же корневой папке.

Связанный контент