Подсчет и перемещение файлов по шаблону
У меня есть много файлов epub, которые я пытаюсь организовать в папки. Все мои файлы названы по одной схеме "Автор - Имя (Год).epub". Я пытаюсь заархивировать файлы, чтобы подсчитать файлы по авторам и переместить их в папку с именем автора, если количество книг превышает 2 (например).
Например, для следующих файлов:
Willis, Connie - [Oxford Time Travel #1] - Doomsday Book (1992).epub
Willis, Connie - [Oxford Time Travel #2] - To Say Nothing of the Dog (1997).epub
Willis, Connie - [Oxford Time Travel #3] - Blackout (2010).epub
Willis, Connie - [Oxford Time Travel #4] - All Clear (2010).epub
Wilson, Robert Charles - Julian Comstock - A Story of 22nd-Century America (2009).epub
Wilson, Robert Charles - [Spin Saga #1] - Spin (2005).epub
Все книги Конни Уиллис должны быть перемещены в папку "Уиллис, Конни", так как их количество превышает 2, тогда как книги Роберта Уилсона не будут затронуты.
Я чувствую себя действительно потерянным и не знаю, с чего начать.
1 ответ
Трехступенчатое решение. cd
в каталог, где находятся файлы, а затем:
Это переместит каждый файл в соответствующий подкаталог:
find . -maxdepth 1 -type f -iname "* -*.epub" \ -exec bash -c ' mkdir "${1%% -*}" 2>/dev/null; mv -n -- "$1" "${1%% -*}"/ ' bash {} \;
"${1%% -*}"
является частью"$1"
до первого-
(Пробел + минус). Мы ожидаем, что подкаталог уже существует;mkdir
потом провалится, все нормально.Это обнаружит подкаталоги с двумя или менее файлами и переместит все их содержимое (обратно) в текущий рабочий каталог:
find . -mindepth 1 -maxdepth 1 -type d \ -exec sh -c ' [ $(find "$1" -maxdepth 1 -type f -printf "\n" | wc -l) -le 2 ] ' sh {} \; \ -exec sh -c ' find "$1" -mindepth 1 -maxdepth 1 -exec mv -n -t ./ -- \{\} + ' sh {} \;
Изменить
-le 2
фрагмент для корректировки числа. Вы можете спросить, почему я говорюfind
печатать переводы строк вместо имен файлов (поведение по умолчанию). Это потому чтоwc
текстовый инструмент, возможные новые строки в именах файлов нарушат мою логику. Явная печать ровно одной новой строки на файл решает эту проблему.Это удалит пустые каталоги:
find . -maxdepth 1 -type d -empty -delete
Должно работать даже без
-empty
так как-delete
(лайкrmdir
) удалит каталог, только если он пуст. Однако в этом случае я хотел бы подавить ожидаемые сообщения об ошибках, говорящие мне, что данный каталог не пуст. Делать это с2>/dev/null
также не позволит мне увидеть неожиданные сообщения об ошибках. Следовательно-empty
тем не мение.
Запустите эти пошаговые инструкции или создайте скрипт. Рекомендуется сделать резервную копию структуры каталогов заранее (например, cp -lr my_directory my_directory_backup
) так, на всякий случай. Некоторые параметры, которые я использовал, не относятся к POSIX, они могут не работать для вас. Также, если у вас уже есть какие-либо подкаталоги, мое решение может их испортить; приспособьте это к своим потребностям тогда.