Для файлов в текущем каталоге:
for name in ./??-??-????.pdf; do
if [[ "$name" =~ (.*)/([0-9]{2})-([0-9]{2})-([0-9]{4})\.pdf ]]; then
echo mv "$name" "${BASH_REMATCH[1]}/${BASH_REMATCH[4]}-${BASH_REMATCH[3]}-${BASH_REMATCH[2]}.pdf"
fi
done
Рекурсивно, в или под текущим каталогом:
find . -type f -name '??-??-????.pdf' -exec bash -c '
for name do
if [[ "$name" =~ (.*)/([0-9]{2})-([0-9]{2})-([0-9]{4})\.pdf ]]; then
echo mv "$name" "${BASH_REMATCH[1]}/${BASH_REMATCH[4]}-${BASH_REMATCH[3]}-${BASH_REMATCH[2]}.pdf"
fi
done' bash {} +
Включение опции оболочки globstar
в bash
позволяет нам сделать следующее (также, как и в предыдущем решении, обрабатывать все файлы в текущем каталоге или ниже):
shopt -s globstar
for name in **/??-??-????.pdf; do
if [[ "$name" =~ (.*)/([0-9]{2})-([0-9]{2})-([0-9]{4})\.pdf ]]; then
echo mv "$name" "${BASH_REMATCH[1]}/${BASH_REMATCH[4]}-${BASH_REMATCH[3]}-${BASH_REMATCH[2]}.pdf"
fi
done
Все три из этих решений используют регулярное выражение для выбора соответствующих частей имен файлов, а затем переставляют эти части в новое имя. Единственная разница между ними заключается в том, как генерируется список путей.
Кодовые префиксы mv
с echo
для безопасности. Чтобы фактически переименовать файлы, удалите echo
(но, по крайней мере, один раз с echo
, чтобы увидеть, что он делает то, что вы хотите).