Форум русскоязычного сообщества Ubuntu


Увидели сообщение с непонятной ссылкой, спам, непристойность или оскорбление?
Воспользуйтесь ссылкой «Сообщить модератору» рядом с сообщением!

Автор Тема: Распаковка архивов с обходом вложенных папок  (Прочитано 4538 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн Nick222

  • Автор темы
  • Активист
  • *
  • Сообщений: 545
    • Просмотр профиля
Есть здоровый диск с множеством папок, у которых масса своих подпапок и т.д.
Папки и архивы названы по-русски, длинные, с пробелами и прочими выкрутасами.

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

Попробовал:

find -name '*.zip' | xargs aunpack -e -S -v *.zip

Две проблемы:

1) aunpack не обрабатывает пробелы в именах файлов.

2) xargs ругается на одинарные кавычки в именах файлов.

Как лучше модифицировать данную строку - или нужно действовать совсем по-другому?

Скорость работы не важна - важно качество распаковки и правильные имена папок после распаковки.

Спасибо :)
Xubuntu 23.04

Оффлайн ALiEN

  • Администратор
  • Старожил
  • *
  • Сообщений: 6733
  • 20% Cooler
    • Просмотр профиля
find -name '*.zip' -exec aunpack -S -v {} \;
find -name '*.zip' -print0 | xargs -0 aunpack -S -v
while read F; do aunpack -S -v "$F"; done < <(find -name '*.zip')
« Последнее редактирование: 05 Июля 2019, 16:09:11 от ALiEN175 »
🖥 AsRock B550M Pro4 :: AMD Ryzen 5 3600 :: 16 GB DDR4 :: AMD Radeon RX 6600 :: XFCE
💻 ACER 5750G :: Intel Core i5-2450M :: 6 GB DDR3 :: GeForce GT 630M :: XFCE

Оффлайн Nick222

  • Автор темы
  • Активист
  • *
  • Сообщений: 545
    • Просмотр профиля
А для кого это "{} \" и что это значит? И где подробно почитать?

И правильно я понимаю, что для такой модели работы для aunpack "-e" просто не нужно?
« Последнее редактирование: 05 Июля 2019, 16:17:55 от Nick222 »
Xubuntu 23.04

Оффлайн ALiEN

  • Администратор
  • Старожил
  • *
  • Сообщений: 6733
  • 20% Cooler
    • Просмотр профиля
А для кого это "{} \" и что это значит? И где подробно почитать?
man find
И правильно я понимаю, что для такой модели работы для aunpack "-e" просто не нужно?
Не обязательно. Aunpack в примерах выше выполняется с одним аргументом.

 
🖥 AsRock B550M Pro4 :: AMD Ryzen 5 3600 :: 16 GB DDR4 :: AMD Radeon RX 6600 :: XFCE
💻 ACER 5750G :: Intel Core i5-2450M :: 6 GB DDR3 :: GeForce GT 630M :: XFCE

Оффлайн Nick222

  • Автор темы
  • Активист
  • *
  • Сообщений: 545
    • Просмотр профиля
Спасибо большое, вроде в тестовом режиме всё работает.

Не подскажете - нельзя ли сделать так, чтобы успешно распакованный файл стирался?
Xubuntu 23.04

Оффлайн ALiEN

  • Администратор
  • Старожил
  • *
  • Сообщений: 6733
  • 20% Cooler
    • Просмотр профиля
нельзя ли сделать так, чтобы успешно распакованный файл стирался?
Зачем?  ???
Вам протестировать архивы надо?
🖥 AsRock B550M Pro4 :: AMD Ryzen 5 3600 :: 16 GB DDR4 :: AMD Radeon RX 6600 :: XFCE
💻 ACER 5750G :: Intel Core i5-2450M :: 6 GB DDR3 :: GeForce GT 630M :: XFCE

Оффлайн Nick222

  • Автор темы
  • Активист
  • *
  • Сообщений: 545
    • Просмотр профиля
Нет - распаковать и стереть успешно распакованные..
Xubuntu 23.04

Оффлайн ALiEN

  • Администратор
  • Старожил
  • *
  • Сообщений: 6733
  • 20% Cooler
    • Просмотр профиля
А, пардон, не так понял)  ;D
Чтобы сам архив удалился.
while read F; do
  aunpack "$F" &&
  rm -v "$F"
done < <(find -name '*.zip')

Не сработает с опцией -S
Cначала потестите.
🖥 AsRock B550M Pro4 :: AMD Ryzen 5 3600 :: 16 GB DDR4 :: AMD Radeon RX 6600 :: XFCE
💻 ACER 5750G :: Intel Core i5-2450M :: 6 GB DDR3 :: GeForce GT 630M :: XFCE

Оффлайн valrust

  • Активист
  • *
  • Сообщений: 364
    • Просмотр профиля
Мой вариант ниже. Не самый элегантный вариант. И лучше перед запуском протестировать.
find -name '*.zip' -print0 | xargs -0 -I arh sh -c 'mkdir "arh-UNPACKED" && unzip -d "arh-UNPACKED" "arh" && rm "arh"' 2>error.log
Далее разбор команды.
Начиная с текущего каталога командой find рекурсивно ищем файлы имя которых заканчивается на ".zip". Для каждого найденного файла его относительный путь в виде строки выводится на стандартный вывод (stdout). Каждая строка заканчивается символом null (аргумент -print0). За это отвечает вот этот кусок:
find -name '*.zip' -print0
Запускаются два процесса find и xarg и связываются между собой так называемым конвейером (pipe). Т.е. всё, что выводит на стандартный вывод (stdout) процесс find передается на стандартный вход (stdin) процесса xarg. Всё это делает вот такой символ:
|
xargs -0 -I arh sh -c 'mkdir "arh-UNPACKED" && unzip -d "arh-UNPACKED" "arh" && rm "arh"'Аргумент "-0", говорит, что на входе нужно ждать строки разделенные символом null.
Аргумент "-I arh" говорит, что перед выполнением в команде для исполнения, нужно символы arh заменить на полученную строку.

Команда xarg принимает на стандартный вход строки и для каждой строки выполняет команду "sh" (командный интерпретатор)с аргументами после "-с". Т.е. xarg для каждой полученной строки из вот такого "шаблона"
sh -c 'mkdir "arh-UNPACKED" && unzip -d "arh-UNPACKED" "arh" && rm "arh"'будет формировать команду для исполнения. Например для входящей строки ./d1/photo12.zip сформируется вот такая команда для исполнения:
sh -c 'mkdir "./d1/photo12.zip-UNPACKED" && unzip -d "./d1/photo12.zip-UNPACKED" "./d1/photo12.zip" && rm "./d1/photo12.zip"'В этой команде символы
&&обозначают, что следующая команда будет выполняться, если предыдущая выполнилась удачно.

2>error.log в файл error.log выводим все сообщения об ошибках. В данном случаи "2" это дескриптор стандартного выхода для ошибок stderr.
« Последнее редактирование: 05 Июля 2019, 21:07:28 от valrust »

Оффлайн ALiEN

  • Администратор
  • Старожил
  • *
  • Сообщений: 6733
  • 20% Cooler
    • Просмотр профиля
valrust, зачем такие сложности?
aunpack -DРазве что имя директории будет совпадать с именем архива.

Цитировать
-D, --subdir
When extracting archives, always create a new directory for the archive even if the archive only contains one file in its root directory.

🖥 AsRock B550M Pro4 :: AMD Ryzen 5 3600 :: 16 GB DDR4 :: AMD Radeon RX 6600 :: XFCE
💻 ACER 5750G :: Intel Core i5-2450M :: 6 GB DDR3 :: GeForce GT 630M :: XFCE

Оффлайн Nick222

  • Автор темы
  • Активист
  • *
  • Сообщений: 545
    • Просмотр профиля
А если по-другому - просто делать список архивов, при попытке распаковки давших ошибку, - тогда куда пихать это "2>error.log" вот в этой строке:

find -name '*.zip' -print0 | xargs -0 aunpack -S -v
Xubuntu 23.04

Оффлайн valrust

  • Активист
  • *
  • Сообщений: 364
    • Просмотр профиля
ALiEN175, проверьте, но у меня параметр -D создает каталог вида Unpack-1234, а автор темы просит
распаковать встречающиеся архивы в лежащие здесь же подпапки с именем, взятым из имени архива.

И второе
Разве что имя директории будет совпадать с именем архива.
Такое не возможно. В одном каталоге двух одинаковых имен не может быть, при этом не важно каталог это или файл.

Оффлайн ALiEN

  • Администратор
  • Старожил
  • *
  • Сообщений: 6733
  • 20% Cooler
    • Просмотр профиля
valrust, потестил:
1. Unpack-XXXX только если каталог уже существует.
2. Имя - конечно же, без расширения
$: ls                             
Archive.zip
$: aunpack -D Archive.zip > /dev/null         
Archive.zip: extracted to `Archive' (forced)
$: ls
Archive  Archive.zip
$: aunpack -D Archive.zip > /dev/null
Archive.zip: extracted to `Unpack-8106' (forced)
$: ls
Archive  Unpack-8106  Archive.zip
$:

Nick222, Спрашивал же про тестирование
while read F;
do zip -T "$F" > /dev/null 2>&1 &&
  echo -e "GOOD: $F" ||
  echo -e "FAIL: $F" | tee -a error.log
done < <(find -name '*.zip')
🖥 AsRock B550M Pro4 :: AMD Ryzen 5 3600 :: 16 GB DDR4 :: AMD Radeon RX 6600 :: XFCE
💻 ACER 5750G :: Intel Core i5-2450M :: 6 GB DDR3 :: GeForce GT 630M :: XFCE

Оффлайн valrust

  • Активист
  • *
  • Сообщений: 364
    • Просмотр профиля
ALiEN175, aunpack при использовании аргумента -D создает каталог для распаковки в текущем каталоге. Вначале создает каталог с именем вида Unpack-####, потом если может переименовывает его в название архива без расширения. Но каталог создается в текущем каталоге, а не там где лежит архив. А автор темы просил (выделение моё)
Нужно обойти все папки и распаковать встречающиеся архивы в лежащие здесь же подпапки с именем, взятым из имени архива.

Оффлайн ALiEN

  • Администратор
  • Старожил
  • *
  • Сообщений: 6733
  • 20% Cooler
    • Просмотр профиля
valrust, точно, пропустил этот момент  :(
Игрался только в одной папке.
🖥 AsRock B550M Pro4 :: AMD Ryzen 5 3600 :: 16 GB DDR4 :: AMD Radeon RX 6600 :: XFCE
💻 ACER 5750G :: Intel Core i5-2450M :: 6 GB DDR3 :: GeForce GT 630M :: XFCE

 

Страница сгенерирована за 0.051 секунд. Запросов: 25.