На основе шаблона, переименование пакетного файла в терминале

48

Мне нужно переименовать следующее:

file_001_loremipsum.png
file_002_dolor.png
file_003_sit.png
file_004_amet.png
file_105_randomness.png

в

upl_loremipsum.png
upl_dolor.png
upl_sit.png
upl_amet.png
upl_randomness.png

Как мне сделать это с помощью одной простой строки команды терминала?

Унамата Санатарай
источник
1
Отказоустойчивая основанная на регулярных выражениях версия Python, которая работает рекурсивно во всех подпапках: stackoverflow.com/a/39698169/191246
ccpizza

Ответы:

79

Решение приведенного выше примера с использованием переименования :

rename -v -n 's/file_\d{1,3}/upl/' file_*.png

Использование:

rename [options] [Perl regex search/replace expression] [files]

От man rename:

   -v, --verbose
           Verbose: print names of files successfully renamed.
   -n, --no-act
           No Action: show what files would have been renamed.

переименование МОЖЕТ принять в качестве аргументов регулярное выражение.

То, на что мы смотрим, это содержание между одинарными кавычками '. Вы можете поместить регулярное выражение через /.

Формула: s/(1)/(2)/где (1)= шаблон поиска и (2)= шаблон замены.

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

Унамата Санатарай
источник
14
Я знаю, что это Ubuntu, но если кто-то окажется здесь, даже если он ищет решение для OS X (я так и сделал), renameего легко установить brew install rename.
Sandstrom
В Ubuntu 18.10 --no-actфлаг установлен --nonoвместо этого. Этот ответ также может быть немного более явным: [files]относится к исходным файлам сопоставления с образцом в текущем каталоге, которые можно потенциально переименовать (например, *сопоставить все, но только в текущем каталоге).
Патрик Дарк
Ваша ссылка указывает на другую rename, которая имеет формат rename from to fileи не поддерживает регулярные выражения. На самом деле, мой дистрибутив Linux (Cent OS 7) имеет именно эту версию.
Алекс Че
6

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

find -iname file_*.png -type f -exec rename -n 's/file_[0-9]{3}(.*\.png)/upl$1/' {} \;

-n после переименования, чтобы проверить, удалите его, чтобы продолжить! -)

вот так вы ассоциируете находку и переименовываете силу.

Лично я использовал это, чтобы переименовать источники заголовка .h в .hpp

find -iname *.h -type f -exec rename 's/(.*\.)h/$1hpp/' {} \;
bcag2
источник
Там в документации для -iname, -typeи -execфлаги в manpages.ubuntu.com/manpages/bionic/man1/find.1.html#expression . ( find --helpне особенно полезно для этой команды.) TL; DR: -inameсоответствует шаблону без учета регистра; -type fсоответствует «обычным файлам»; и -execвыполняет выражение, пока не встретит ;символ (точка с запятой).
Патрик Дарк
5

Это может быть сделано с небольшим волшебством расширения параметра bash!

for f in file_[0-9]*_*; do mv $f upl_${f#file_[0-9]*_}; done

file_[0-9]*_*;- Первый шаблон используется для прохождения всех файлов, которые начинаются с 'file_anynumber_'
${f#file_[0-9]*_}- Второй шаблон file_[0-9]*_используется в расширении параметра, которое сообщает bash об удалении 'file_anynumber_' из начала строки.

Для получения дополнительной информации о Parameter expansion:

man bash
Башарат Сиалви
источник
Обратите внимание, что здесь используются глобусы, а не регулярные выражения, поэтому [0-9]*будет соответствовать одна цифра, за которой следует любая строка. Вероятно, есть лучший способ сопоставить только цифры, но я не могу придумать ничего краткого.
wjandrea
Не могли бы вы также предложить способ рекурсивного выполнения этой команды во всех подкаталогах?
Франческо Д.М.