Массовое переименование файлов, ведение временных меток, исключая некоторые
В 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
Дальнейшее чтение:
- https://www.regular-expressions.info/: если вам нужна помощь с регулярными выражениями
- Страница man bash(1): поиск
=~
оператор, а затем читать на специальномBASH_REMATCH
массив - findutils | Регулярные выражения: подробности об удивительном разнообразии регулярных выражений, поддерживаемых GNU
find
а такжеlocate
,