Переименование файлов в Linux с помощью регулярного выражения
У меня была группа файлов, которую я хотел бы последовательно переименовывать, файлы называются такими вещами, как
"System-Log-01-01-2009-NODATA.txt"
"Something-Log-01-01-2009-NODATA.txt"
И я хотел их в нижнем регистре, ггггммдд, расширение.log
"system.20090101.log"
"something.20090101.log"
7 ответов
Для этого я писал сценарии на Perl, пока не обнаружил команду переименования.
Он принимает регулярное выражение Perl для переименования:
для этого я просто набрал две команды:
rename 's/(\w+)-(\w+)-(\d\d)-(\d{4})-NODATA.txt\$1.$4$3$2.log$//' *
rename 'y/A-Z/a-z/' *.log
Для некоторых дистрибутивов, хотя, rename
не имеет этой функции (см. его справочную страницу), и вам, возможно, придется установить perl-rename
или же prename
,
mmv - это стандартная утилита linux для перемещения / переименования нескольких файлов. Он доступен в репозиториях для большинства дистрибутивов. Для вашего примера выше вы можете сделать:
mmv *-Log-*-*-*-NODATA.txt #l1.#4#3#2.log
Для получения дополнительной информации, прочитайте эту статью или справочную страницу.
Поскольку у меня нет команды переименования, я полагаюсь на это:
for myfile in /my/folder/*; do
target=$(echo $myfile|sed -e 's/foo/bar/g')
mv "$myfile" "$target"
done
rename
Утилита не очень "стандартная". Каждый дистрибутив поставляется с другим rename
инструмент. Например, здесь, на Gentoo, rename
из sys-apps/util-linux
пакет и не поддерживает регулярные выражения.
Хэмиш Даунер предложил mmv
Вроде бы полезно, специально для использования внутри скриптов.
С другой стороны, в общем случае вы можете захотеть переименовать. Она имеет qmv
а также qcp
Команды, которые откроют текстовый редактор по вашему выбору (мои предпочтения: Vim) и позволят вам редактировать целевые имена файлов там. После сохранения и закрытия редактора, qmv
/qcp
сделаю все переименование.
И то и другое mmv
а также qmv
достаточно умен, чтобы переименовывать файлы в правильном порядке, а также обнаруживать циклическое переименование, и автоматически создает временный файл, если это необходимо.
Чтобы быть справедливым:
rename 's/(\w+)-(\w+)-(\d\d)-(\d{4})-NODATA.txt\$1.$4$3$2.log$//' *.txt
дает этот вывод:
Use of uninitialized value $4 in regexp compilation at (eval 1) line 1.
Use of uninitialized value $3 in regexp compilation at (eval 1) line 1.
Use of uninitialized value $2 in regexp compilation at (eval 1) line 1.
Но:
rename -n 's/(\w+)-\w+-(\d{2})-(\d{2})-(\d{4})-NODATA\.txt$/$1.$4$3$2\.log/' *.txt && rename 'y/A-Z/a-z/' System.20090101.log
дает правильный вывод:
System-Log-01-01-2009-NODATA.txt renamed as System.20090101.log
System.20090101.log renamed as system.20090101.log
замена {-n} переключателя на {-v}
Я создал небольшой скрипт bash для этого:
#!/bin/bash
for f in `ls /path/to/folder`; do
# Create new filename from the old one
# This example replaces A (upper case) with a (lower case)
new_file=`echo "$new_file" | tr A a`
# Rename the file
mv "$f" "$new_file"
done
Я наткнулся на инструмент командной строки Python под названием regex-rename. Чтобы установить его, просто запустите:
pip3 install --user regex-rename
Чтобы проверить регулярное выражение:
regex-rename '(\w+)-(\w+)-(\d+)-(\d+)-(\d+)-NODATA(\.txt)'
Фактическое переименование будет таким:
regex-rename '(\w+)-(\w+)-(\d+)-(\d+)-(\d+)-NODATA(\.txt)' '\1.\5\4\3\6' --rename