Как я могу заставить 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 для «мусорных путей», но я хочу сохранить структуру подкаталога, а не структуру каталогов верхнего уровня. Как я могу это сделать?

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 
  • У вас возникли проблемы с распаковкой нескольких файлов
  • Возможно ли в unix выполнять поиск внутри zip-файлов
  • Как исключить каталог при копировании файлов
  • Как добавить огромный архив в архив и удалить его параллельно
  • Zip не сжимает файлы при застегивании
  • Есть ли способ конвертировать zip в tar без извлечения его в файловую систему?
  • Защищенные паролем zip-архивы открываются без пароля
  • архивирование файлов без изменений
  • Разархивировать архив с одним файлом и переименовать вывод в соответствии с именем архива
  • Как создать ZIP-архив, который сохраняет только структуру целевого каталога и ниже?
  • распаковать каталог в unix
  • Преобразование Windows-созданного ZIP в Linux (проблемы с внутренними путями)
  • Linux и Unix - лучшая ОС в мире.