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

312
Paul Poloskov

У меня есть много файлов 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, тогда как книги Роберта Уилсона не будут затронуты.

Я чувствую себя действительно потерянным и не знаю, с чего начать.

0
Вы можете получить ответы, которые делают это за один шаг, но я думаю, что возможен также подход, разбитый на более простые шаги: (1) обнаружение авторов и создание каталогов; (2) переместить каждый файл в соответствующий каталог (хотя может быть разумно объединить шаги 1 и 2, хотя); (3) обнаруживать каталоги с двумя или менее файлами и перемещать файлы обратно в основной каталог; (4) обнаружить пустые каталоги и удалить их. // Можете ли вы выполнить какой-либо из этих шагов? Kamil Maciorowski 6 лет назад 1

1 ответ на вопрос

0
Kamil Maciorowski

Трехступенчатое решение. cdв каталог, где находятся файлы, а затем:

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

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

    "$"является частью "$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, они могут не работать для вас. Также, если у вас уже есть какие-либо подкаталоги, мое решение может их испортить; приспособьте это к своим потребностям тогда.

Похожие вопросы