Regex и shell - многократное рекурсивное переименование - PullRequest
1 голос
/ 05 марта 2012

У меня есть папка с несколькими сотнями папок внутри.Эти папки содержат еще одну папку, называемую изображениями, и в этой папке иногда есть строго числовой файл .jpg.Иногда в папке также есть другие файлы JPG, но их нужно игнорировать, если они не являются строго числовыми.

Я хотел бы узнать, как написать сценарий, который при запуске в заданном режимепапку, просмотрите каждую подпапку и найдите этот числовой файл.Затем он добавит суффикс "_n" к копии каждого, если такого файла еще не существует.

Можно ли это легко сделать через терминал unix?

Чтобы быть более точным, это структура, с которой я имею дело:

  • главная папка
    • 18556
      • images
        • 2234.jpg
    • 47772
      • изображения
        • 2234.jpg
        • 2234_n.jpg
        • some_pic.jpg
    • 77377
      • изображения
    • 88723
      • изображения
        • 22.jpg
        • some_pic.jpg

После запуска сценария, ситуация будет выглядеть следующим образом:

  • главная папка
    • 18556
      • images
        • 2234.jpg
        • 2234_n.jpg
    • 47772
      • изображения
        • 2234.jpg
        • 2234_n.jpg
        • some_pic.jpg
    • 77377
      • images
    • 88723
      • images
        • 22.jpg
        • 22_n.jpg
        • some_pic.jpg

Обновление: Извините за опечатку, я случайно поместил 2235 в 47772. Обновление 2: Что касается 2-го комментария к ответу математического.coffee, то операционная система, на которой я сейчас (на работе) - это MacOS, но мои основные машины работают под CentOS и Ubuntu вдома, поэтому я просто предположил, что моя ситуация применима ко всем системам на основе Unix.

Ответы [ 2 ]

4 голосов
/ 05 марта 2012

Вы можете использовать переключатель -regex для find для соответствия /somefolder/images/numeric.jpg:

find -type f -regex './[^/]+/images/[0-9]+\.jpg$'

Редактировать : уточнение из @JonathanLeffler: добавьте -type f, чтобы найти, чтобы он только находил файлы (т.е. не соответствует каталогу с именем «12345.jpg»).

./[^/]+/ - для первой папки (если эта первая папка также всегда числовая, вы можете изменить ее на [0-9]+).

[0-9]+\.jpg$ означает файл jpg, имя файла которого только числовое. Вы можете изменить jpg на jpe?g, чтобы разрешить .jpeg, но это ваше дело.

Тогда нужно скопировать их в xxx_n.jpg.

for f in $(find -type f -regex './[^/]+/images/[0-9]+\.jpg$')
do
    # replace '.jpg' in $f (filename) with '_n.jpg'
    newf=${f/\.jpg/_n\.jpg}
    # see if this new file exists
    if [ ! -f $newf ];
    then
        # if not exists, copy it.
        cp "$f" "$newf"
    fi
done
1 голос
/ 05 марта 2012

Какой должна быть логика переименования в папке 47772? Если мы предполагаем, что вы хотите переименовать все файлы, состоящие только из цифр, в числа + _n

С mmv вы можете написать это как:

mmv "[0-9][0-9]*.jpg" "#1#2#3_n.jpg"

Примечание: mmv для перемещения; mcp для копирования, и поэтому больше подходит для этого вопроса.

Вопрос Вейдера: Я проверил справочную страницу, и проблема в том, что это немного странно. Я думал, что [0-9] * будет соответствовать нулю или более цифр. Оказывается, это предположение было неверным. Проблема в том, что я не могу сказать, что хочу два или более чисел в начале названия.

Итак, [0-9] [0-9] * соответствует имени, начинающемуся как минимум с двух чисел (после этого все остальное занимает до .. Теперь каждый [0-9] - это один шаблон, и поэтому я должен был сделать шаблон в: "# 1 # 2 # 3_n.jpg" Например, 1234.jpg У меня # 1 = 1; # 2 = 2, # 3 = 34 Итак

#1#2#3 -> 1234;  _n appends the _n and .jpg the extension

Однако он также переименовал бы файлы с помощью 12some_other_stuff.jpg sot 12some_other_stuff_n.jpg. Это не идеально, но достигает в этом контексте того, что было задумано.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...