Как я могу заставить unzip / zip не создавать подкаталог, когда я его извлекаю?

В зависимости от того, как создается zip-файл, иногда он извлекает все файлы напрямую, а иногда и извлекает файлы в подкаталог.

Если последнее верно, как заставить команду unzip «игнорировать» этот каталог первого уровня?

Пример:

 cd /tmp wget http://omeka.org/files/omeka-1.5.1.zip mkdir omeka unzip omeka-1.5.1.zip -d omeka/ cd omeka/ ll 

То, что я получаю, это /tmp/omeka/omeka-1.5.1/ :

 total 12 drwxr-xr-x 3 root root 4096 2012-05-08 18:44 ./ drwxrwxrwt 6 root root 4096 2012-05-08 18:44 ../ drwxr-xr-x 5 root root 4096 2012-04-20 14:54 omeka-1.5.1/ 

Я хочу, чтобы файлы были извлечены в /tmp/omeka/ (один уровень вверх и номер версии, включенный в структуру каталогов)

 /tmp/omeka/(files) 

Я знаю, что я могу использовать параметр -j для «мусорных путей», но я хочу сохранить структуру подкаталога, а не структуру каталогов верхнего уровня. Как я могу это сделать?

  • Depsolving для php-pecl-zip
  • Извлеките список .zip-файлов в один новый каталог каждый, имя каталога, которое будет взято из имени zip-файла
  • Замещать содержимое папки без включения самой папки
  • Настройка исполнения права на весь каталог - это хорошая или плохая идея?
  • В сценарии оболочки, Как передать переменную другое значение после выполнения одного задания?
  • Раскройте архив gz с расширением zip
  • Можно ли получить «старую» временную марку?
  • Кодирование zip-файла
  • 6 Solutions collect form web for “Как я могу заставить unzip / zip не создавать подкаталог, когда я его извлекаю?”

    Используйте файловую систему FUSE, которая позволяет просматривать архивы, такие как каталоги, такие как AVFS . Используйте cp для извлечения файлов в каталог по вашему выбору.

     mountavfs cp -Rp ~/.avfs/tmp/omeka-1.5.1.zip\#/omeka-1.5.1 omeka 

    Поскольку мы предполагаем, что в архиве имеется один файл верхнего уровня, вы можете сократить его до

     cp -Rp ~/.avfs/tmp/omeka-1.5.1.zip\#/* omeka 

    Если ваш zip-файл не содержит структуры каталогов или вам не нужно его сохранять, вы можете использовать это:

     cd /tmp wget http://omeka.org/files/omeka-1.5.1.zip unzip -j omeka-1.5.1.zip -d omeka cd omeka ll 

    Этот скрипт не является надежным, но работает в простых случаях:

     ... dest=omeka unzip omeka-1.5.1.zip -d $dest/ if [ `ls $dest | wc -l` == 1 ]; then subdir=`ls $dest` mv $dest/$subdir/* $dest/ rmdir $dest/$subdir fi 

    Он просто проверяет, существует ли ровно один подкаталог, и если это так, все перемещается из него, а затем удаляет его.

    Я только что зарегистрировался сегодня, поэтому я не могу ответить на вопрос @SteveBennet и не могу добавить комментарий там.

    Основываясь на его ответе, я создал такую ​​рекурсивную функцию:

     ... shopt -s dotglob # To include hidden files in the move command function moveSub { local dest=$1 if [ `ls $dest | wc -l` == 1 ]; then local subdir=`ls $dest` moveSub "$dest/$subdir" mv $dest/$subdir/* $dest/ rmdir $dest/$subdir fi } moveSub "$dest" 

    Так же, как @SteveBennet сказал: этот скрипт не является надежным, но работает в простых случаях.

    Надеюсь, это полезно.

    Необходимость выглядит как patch --strip=n option

    Хотелось бы иметь такую ​​возможность, как patch --strip=number (или -pnumber ), которая -pnumber компоненты number пути (см. Сравнение и слияние файлов: патч-каталоги ).

    Другое решение, применимость

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

    Когда это решение работает и доступно решение Gilles, последнее тоже будет работать. Однако это решение не требует наличия файловой системы FUSE.

    Как это сделать

    Предполагая, что вы знаете дополнительный каталог, в вашем случае omeka-1.5.1 вы можете сделать это:

     mkdir omeka ln -s . omeka/omeka-1.5.1 # create a symlink that redirects output unzip omeka-1.5.1.zip -d omeka/ rm omeka/omeka-1.5.1 # remote symlink 

    unzip попытается разархивировать omeka-1.5.1 который на самом деле является символической omeka-1.5.1 на содержащий omeka-1.5.1 . В результате файлы будут omeka в omeka напрямую.

    Возможные варианты

    Вы можете представить варианты для перенаправления одной или нескольких частей иерархии depeer.

     ln -s ../myfoo omeka/omeka-1.5.1/foo ln -s ../../mybarxyzzy omeka/omeka-1.5.1/subdir/bar 

    Вывод

    Это решение несколько специфично, но оно имеет свои варианты использования, и я просто использовал его.

    Скорее всего, вы хотите запустить unzip с параметром -j , как в:

     unzip -j files.zip -d ./output/ 

    Но вы можете быть удивлены его поведением:

    -j мусорные пути. Структура каталогов архива не воссоздана; все файлы помещаются в каталог извлечения (по умолчанию – текущий).

    Если вы извлечете files.zip в выходной каталог ./output и вы получите это как результат:

     ./output/files/subfolder1/f1 ./output/files/subfolder1/f2 

    то опция -j даст вам это (все пути полосатые):

     ./output/f1 ./output/f2 
    Linux и Unix - лучшая ОС в мире.