Скрипт Bash для перемещения по папкам, распаковки и перемещения файлов на один каталог вверх

Скрипт Bash для перемещения по папкам, распаковки и перемещения файлов на один каталог вверх

У меня есть группа папок, в каждой из которых есть zip-файлы, которые могут содержать 1 или 2 файла в каждой новой папке. (см. схему ниже)

Я хочу указать скрипту каталог верхнего уровня и заставить его пройти по каждому подкаталогу, извлечь содержимое zip-архива, переместить содержимое этого подкаталога на один уровень вверх (удалив исходный заархивированный файл по желанию).

--before--
Photos
-2018
--jan.zip
[--jan1     ]--\
[---jan1.pdf]---}-contents of Zipped file
[---jan1.JPG]--/
--feb.zip
[--feb1     ]--\
[---feb1.pdf]---}-contents of Zipped file
[---feb1.JPG]--/
...

--after--
Photos
-2018
--jan1.pdf
--jan1.JPG
--feb1.pdf
--feb1.JPG

решение1

Прежде чем выполнять что-либо из нижеперечисленного, пожалуйста, сделайте (рекурсивное) копирование вашего каталога верхнего уровня — просто на всякий случай.

Тогда вы можете достичь желаемого следующим образом:

Сделайте каталог верхнего уровня (photos) вашим текущим рабочим каталогом. Затем извлеките все zip-файлы:

find . -iname "*.zip" -execdir unzip {} \;

Теперь переместите содержимое извлеченных каталогов на один уровень выше:

find . -type f ! -iname "*.zip" -execdir mv "$(basename {})" .. \;

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

find . -mindepth 2 -maxdepth 2 -type d -delete

Прежде чем удалить zip-файлы, дважды проверьте, что все в порядке. Затем вы можете выполнить удаление с помощью

find . -iname "*.zip" -delete

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

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

#!/bin/bash
cd "$1"
find . -iname "*.zip" -execdir unzip {} \;
find . -type f ! -iname "*.zip" -execdir mv "$(basename {})" .. \;
find . -mindepth 2 -maxdepth 2 -type d -delete
find . -iname "*.zip" -delete

Если вы дадите ему имя «extract» (и установите разрешение на выполнение), его можно будет использовать в его собственном каталоге следующим образом (предполагая, ~/photosчто это ваш каталог верхнего уровня):

./extract ~/photos

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

Связанный контент