У меня есть сценарий, который извлекает tar.gz-файл в указанную подпапку mysubfolder :
mkdir mysubfolder; tar --extract --file=sourcefile.tar.gz --strip-components=1 --directory=mysubfolder;
Есть ли эквивалентный способ сделать это с zip-файлом?
Ответы:
Как сказал Матиас,
unzip
такой опции нет, но однострочный скрипт bash может сделать эту работу.Проблема в том, что наилучший подход зависит от формата вашего архива. Решение, которое предполагает один каталог верхнего уровня, с треском провалится, если контент находится непосредственно в корне архива (подумайте о
/a/foo
/b/foo
/foo
хаосе удаления/a
и/b
).И тот же сбой происходит с
tar --strip-component
. Не существует единого решения для всех.Итак, для удаления корневого каталога, предполагая, что есть один (и только один):
Просто убедитесь, что файлы / каталоги второго уровня не имеют одинакового имени родителя верхнего уровня (например,
/foo/foo
). Но/foo/bar/foo
и/foo/bar/bar
все в порядке. Если это так, или вы просто хотите быть в безопасности, вы можете использовать временный каталог для извлечения:Если вы используете Bash, вы можете проверить, является ли верхний уровень одним каталогом или нет:
Говоря о Bash, вы должны
dotglob
включить скрытые файлы, и вы можете обернуть все в одну удобную функцию:Теперь вставьте это в свой
~/.bashrc
или,~/.profile
и вам больше никогда не придется беспокоиться об этом. Просто используйте как:(обратите внимание, он будет создан автоматически
mysubfolder
для вас, если он не существует)источник
Я не смог найти такой вариант на страницах справочника
unzip
, поэтому боюсь, что это невозможно. :(Однако (в зависимости от ситуации) вы можете обойти это. Например, если вы уверены, что единственный каталог верхнего уровня в zip-файле имеет имя,
foo-
за которым следует номер версии, вы можете сделать что-то вроде этого:источник
rm -rf foo-*
специально, потому что это потенциально опасно. Что, если там уже была папка с именемfoo-bar
? Обратите внимание, что извлечение выполняется в/tmp
папке, которая время от времени очищается автоматически.&&
: данный шаг происходит только в том случае, если предыдущий шаг был успешным, поэтому последний (rm
) выполняется только в том случае, если все шаги выполнены без ошибок./tmp/some-hardcoded-folder-name
временную папку, а использовать ееmktemp
для этого: она гарантирует, что такой папки не будет. Проверьте мой ответ ниже.Вы можете использовать
-j
для мусорных путей (не создавать каталоги). Это рекомендуется только для довольно распространенных одноуровневых архивов. Архивы с многоуровневой структурой каталогов будут сглажены - это может даже привести к конфликтам имен для извлекаемых файлов.Со страницы руководства по распаковке:
источник