Как поменять местами слова в имени файла с помощью оболочки?

Как поменять местами слова в имени файла с помощью оболочки?

Один из моих клиентов — школа. На их файловом сервере все проекты имеют каталог с одинаковой схемой именования.

<фамилия>, <имя> <второе имя>? - <описание проекта>

Например:

Миллер, Джон Эндрю - Подробное описание проекта
Уиллис, Брюс - Описание, возможно с запятой
Льюис, Мэри-Джейн - Описание - Включая минус

Новое соглашение об именовании:

<имя> <второе имя>? <фамилия> - <описание проекта>

Например:

Джон Эндрю Миллер - Подробное описание проекта
Брюс Уиллис - Описание, возможно с запятой
Мэри-Джейн Льюис - Описание - Включая минус

Как теперь переименовать все существующие папки в соответствии с новой конвенцией?

решение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

Что касается сопоставления, вам нужно быть очень осторожным, чтобы построить что-то надежное. Например, предположим, что имя и отчество

  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.

Связанный контент