Как сказал Матиас, unzip
такой опции нет, но однострочный скрипт bash может сделать эту работу.
Проблема в том, что наилучший подход зависит от формата вашего архива. Решение, которое предполагает один каталог верхнего уровня, с треском провалится, если контент находится непосредственно в корне архива (подумайте о /a/foo
/b/foo
/foo
хаосе разборки /a
и /b
).
И тот же сбой происходит с tar --strip-component
. Не существует единого решения для всех.
Итак, для удаления корневого каталога, предполагая, что есть один (и только один):
unzip -d "$dest" "$zip" && f=("$dest"/*) && mv "$dest"/*/* "$dest" && rmdir "$"
Просто убедитесь, что файлы / каталоги второго уровня не имеют одинакового имени родителя верхнего уровня (например, /foo/foo
). Но /foo/bar/foo
и /foo/bar/bar
все в порядке. Если это так, или вы просто хотите быть в безопасности, вы можете использовать временный каталог для извлечения:
temp=$(mktemp -d) && unzip -d "$temp" "$zip" && mkdir -p "$dest" && mv "$temp"/*/* "$dest" && rmdir "$temp"/* "$temp"
Если вы используете Bash, вы можете проверить, является ли верхний уровень одним каталогом или нет:
f=("$temp"/*); (( ${#f[@]} == 1 )) && [[ -d "$" ]] && echo "Single dir!"
Говоря о Bash, вы должны dotglob
включить скрытые файлы, и вы можете обернуть все в одну удобную функцию:
unzip-strip() ( local zip=$1 local dest=$ local temp=$(mktemp -d) && unzip -d "$temp" "$zip" && mkdir -p "$dest" && shopt -s dotglob && local f=("$temp"/*) && if (( ${#f[@]} == 1 )) && [[ -d "$" ]] ; then mv "$temp"/*/* "$dest" else mv "$temp"/* "$dest" fi && rmdir "$temp"/* "$temp" )
Теперь вставьте это в свой ~/.bashrc
или, ~/.profile
и вам больше никогда не придется беспокоиться об этом. Просто используйте как:
unzip-strip sourcefile.zip mysubfolder
(обратите внимание, он будет создан автоматически mysubfolder
для вас, если он не существует)