В некоторых случаях, скажем, у меня есть 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
Редактировать:Предложение Марка Перримана, вероятно, лучше. Я только что понял, что моя команда проверяет, содержатся ли файлы в подпапках, но не проверяет, содержатся ли все они в одной и той же корневой папке.