Подсчет и перемещение файлов по шаблону

У меня есть много файлов 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 в каталог, где находятся файлы, а затем:

  1. Это переместит каждый файл в соответствующий подкаталог:

    find . -maxdepth 1 -type f -iname "* -*.epub" \
       -exec bash -c '
           mkdir "${1%% -*}" 2>/dev/null; mv -n -- "$1" "${1%% -*}"/
       ' bash {} \;
    

    "${1%% -*}" является частью "$1" до первого - (Пробел + минус). Мы ожидаем, что подкаталог уже существует; mkdir потом провалится, все нормально.

  2. Это обнаружит подкаталоги с двумя или менее файлами и переместит все их содержимое (обратно) в текущий рабочий каталог:

    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 текстовый инструмент, возможные новые строки в именах файлов нарушат мою логику. Явная печать ровно одной новой строки на файл решает эту проблему.

  3. Это удалит пустые каталоги:

    find . -maxdepth 1 -type d -empty -delete
    

    Должно работать даже без -empty так как -delete (лайк rmdir) удалит каталог, только если он пуст. Однако в этом случае я хотел бы подавить ожидаемые сообщения об ошибках, говорящие мне, что данный каталог не пуст. Делать это с 2>/dev/null также не позволит мне увидеть неожиданные сообщения об ошибках. Следовательно -empty тем не мение.

Запустите эти пошаговые инструкции или создайте скрипт. Рекомендуется сделать резервную копию структуры каталогов заранее (например, cp -lr my_directory my_directory_backup) так, на всякий случай. Некоторые параметры, которые я использовал, не относятся к POSIX, они могут не работать для вас. Также, если у вас уже есть какие-либо подкаталоги, мое решение может их испортить; приспособьте это к своим потребностям тогда.

Другие вопросы по тегам