
Один из моих клиентов — школа. На их файловом сервере все проекты имеют каталог с одинаковой схемой именования.
<фамилия>, <имя> <второе имя>? - <описание проекта>
Например:
Миллер, Джон Эндрю - Подробное описание проекта Уиллис, Брюс - Описание, возможно с запятой Льюис, Мэри-Джейн - Описание - Включая минус
Новое соглашение об именовании:
<имя> <второе имя>? <фамилия> - <описание проекта>
Например:
Джон Эндрю Миллер - Подробное описание проекта Брюс Уиллис - Описание, возможно с запятой Мэри-Джейн Льюис - Описание - Включая минус
Как теперь переименовать все существующие папки в соответствии с новой конвенцией?
решение1
Поскольку часть описания имени файла может содержать шаблон -
(дефис между двумя пробелами), вы можете изменить его на какой-либо символ, которыйне делаетвстречаются в части описания. Я выбрал £
, но это чисто произвольно.
rename 's/ - /£/' *
rename 's/([^,]*), ([^£]*)£/$2 $1 - /' *
s/ - /£/' tells rename to replace the first instance of
- it finds with
£ . The second command is a bit more complicated. Parenthases (
() ) are used to group selections together -- so everything that matches the pattern within the first set of parens can be called later as
$1 (all the way up to
$9 ).
[^,] means 'any character, except for
,';
means 'zero or more of the previous character';
[^,]` означает «ноль или более любых символов, кроме запятой». Поскольку rename по умолчанию является жадным, он соответствует максимально длинной строке.
Остальное, я думаю, вытекает вполне естественно.
Если вы не уверены, встречается ли символ где-либо в имени файла, просто выполните:
printf '%s\n' *£*
Если у вас есть perl-rename:
rename 's/([^,]*), (.*) - /$2 $1 - /' *
Это приведет к сбою, если часть описания имени файла содержит -
(то есть -
между двумя пробелами).
Вы должны проверить это с помощью -n
флага, который не будет переименовывать файлы, но покажет, что это такое.бысделал:
rename -n 's/([^,]*), (.*) - /$2 $1 - /' *
решение2
Что касается сопоставления, вам нужно быть очень осторожным, чтобы построить что-то надежное. Например, предположим, что имя и отчество
- должно начинаться с буквы
- может содержать дефисы (но не другие знаки препинания или пробелы)
ваш шаблон имени становится чем-то вроде [[:alpha:]][[:alpha:]-]*
. Затем вы можете сделать необязательное разделенное пробелами среднее имя, ((?: [[:alpha:]][[:alpha:]-]*)?)
где дополнительная структура группы без захвата просто помогает сохранить номера групп захвата прямыми, когда среднее имя пустое. Собираем это вместе, например, с помощью команды rename на основе perl
rename -nv -- 's/(^[^,]*), ([[:alpha:]][[:alpha:]-]*)((?: [[:alpha:]][[:alpha:]-]*)?)/$2$3 $1/' *
или (допуская более общие пробелы между полями вместо одиночных пробелов)
rename -nv -- 's/(^[^,]*),\s+([[:alpha:]][[:alpha:]-]*)((?:\s+[[:alpha:]][[:alpha:]-]*)?)/$2$3 $1/' *
Переключатель -n
является пустым, т.е. он не будет выполнять переименования, пока не будет удален. Если у вас нет переименования на основе perl, вы можете использовать комбинацию perl
и mv
.