Назад | Перейти на главную страницу

Переименование файлов в Linux с помощью регулярного выражения

У меня была группа файлов, которые я хотел бы последовательно переименовать, файлы имеют такие названия, как

"System-Log-01-01-2009-NODATA.txt"
"Something-Log-01-01-2009-NODATA.txt"

И я хотел, чтобы они были в нижнем регистре, ггггммдд, расширение .log

"system.20090101.log"
"something.20090101.log"

Я писал для этого Perl-скрипты, пока не обнаружил команду rename.

Он принимает регулярное выражение 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.

ммв - это стандартная утилита 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 util не очень "стандартный". Каждый дистрибутив поставляется с разными rename инструмент. Например, здесь, в Gentoo, rename из sys-apps/util-linux пакет и не поддерживает регулярное выражение.

Хэмиш Даунер предложил mmvВроде полезно, специально для использования внутри скриптов.

С другой стороны, в общем случае вам может понадобиться renameutils. Оно имеет 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