Массовое переименование файлов, ведение временных меток, исключая некоторые

В Ubuntu 18.10 добавлено использование mmv для добавления имен папок (даты) к именам файлов в нескольких папках (здесь для просмотра результатов установлен флаг '-n'):

mmv -n './????-??-??*/*.*' './#1#2#3#4-#5#6-#7#8#9/#1#2#3#4#5#6#7#8-#10.#11'

который, например, преобразует:

./2018-12-11/DSC05287.ARW -> ./2018-12-11/20181211-DSC05287.ARW

Он также конвертирует:

./2018-12-11/20181211-DSC05287.ARW -> ./2018-12-11/20181211-20181211-DSC05287.ARW

сохраняя отметки времени.

Некоторые файлы уже были переименованы, некоторые нет.

Как я могу отфильтровать команду, чтобы исключить файлы, соответствующие шаблону - те, которые начинаются с 8-значного числа, за которым следует дефис?

Или мне нужен другой подход?

1 ответ

Я не фанат универсальных утилит переименования, так что вот как бы я это делал, используя только "стандартное (GNU) оборудование", в частности bash, find а также mv,

Предполагая, что вы заинтересованы только в файлах, которые находятся на один уровень ниже (так find -maxdepth 2), и, в частности, игнорирование файлов, которые уже были ранее переименованы (но проверка работоспособности с обратными ссылками регулярного выражения, чтобы избежать предположений):

find -regextype egrep -maxdepth 2 -type f \! -regex '\./([0-9]{4})-([0-9]{2})-([0-9]{2}).*/\1\2\3-.+' | while read f; do

  if [[ $f =~ ^(\./([0-9]{4}-[0-9]{2}-[0-9]{2}).*)/(.+)$ ]]; then
    # The above regex groups its matches into:
    # ${BASH_REMATCH[1]} = the dir pathname
    # ${BASH_REMATCH[2]} = the date in the dir pathname (remember to strip its dashes)
    # ${BASH_REMATCH[3]} = the file name

    mv -v "$f" "${BASH_REMATCH[1]}"/"${BASH_REMATCH[2]//-}-${BASH_REMATCH[3]}"

  fi

done

И исправить те, которые уже были неправильно "двойными" (опять же, используя обратные ссылки, чтобы избежать необоснованных предположений):

find -regextype egrep -maxdepth 2 -type f -regex '\./([0-9]{4})-([0-9]{2})-([0-9]{2}).*/\1\2\3-\1\2\3-.+' | while read f; do

  if [[ $f =~ ^(\./.+)/([0-9]{8})-[0-9]{8}-(.+)$ ]]; then
    # The above regex groups its matches into:
    # ${BASH_REMATCH[1]} = the dir pathname
    # ${BASH_REMATCH[2]} = the first date chunk
    # ${BASH_REMATCH[3]} = the filename "tail"

    mv -v "$f" "${BASH_REMATCH[1]}/${BASH_REMATCH[2]}-${BASH_REMATCH[3]}"

  fi

done

Дальнейшее чтение:

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