Регулярные выражения, группы захвата и знак доллара

Читая книгу о bash, я знакомил с регулярными выражениями (я новичок в них) с примером:

rename -n 's/(.*)(.*)/new$1$2/' *

'file1' would be renamed to 'newfile1'
'file2' would be renamed to 'newfile2'
'file3' would be renamed to 'newfile3'

К сожалению, в этом примере не было разбивки. Я как бы понимаю, что такое группы захвата, и что .* жадный и будет соответствовать всем символам, но я не уверен, зачем нужны две группы захвата. Кроме того, я понимаю, что $ представляет собой конец строки, но я не уверен, что на самом деле здесь делает $1$2. Цените любую предоставленную информацию.

Попытка исследовать группы захвата и $ для некоторых подобных примеров с пояснениями, но не удалась.

Важно понимать, что это регулярное выражение будет обрабатываться командой rename, а не самим bash, и его синтаксис может несколько отличаться от регулярных выражений bash (очевидно, что bash не помещает свои группы захвата в $1, $2, и т. д., но в ${BASH_REMATCH[1]} и т. д. И grep, и sed, и awk, и т. д. все делают немного по-разному..

Gordon Davisson 19.11.2022 19:29

@ Felthorn3 - Что это за книга?

Jim Davis 19.11.2022 20:31

@JimDavis, это «Learn Bash the Hard Way» Яна Миелла.

Felthorn3 20.11.2022 14:59
Шаблоны Angular PrimeNg
Шаблоны Angular PrimeNg
Как привнести проверку типов в наши шаблоны Angular, использующие компоненты библиотеки PrimeNg, и настроить их отображение с помощью встроенной...
Создайте ползком, похожим на звездные войны, с помощью CSS и Javascript
Создайте ползком, похожим на звездные войны, с помощью CSS и Javascript
Если вы веб-разработчик (или хотите им стать), то вы наверняка гик и вам нравятся "Звездные войны". А как бы вы хотели, чтобы фоном для вашего...
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Начала с розового дизайна
Начала с розового дизайна
Pink Design - это система дизайна Appwrite с открытым исходным кодом для создания последовательных и многократно используемых пользовательских...
Шлюз в PHP
Шлюз в PHP
API-шлюз (AG) - это сервер, который действует как единая точка входа для набора микросервисов.
14 Задание: Типы данных и структуры данных Python для DevOps
14 Задание: Типы данных и структуры данных Python для DevOps
проверить тип данных используемой переменной, мы можем просто написать: your_variable=100
0
3
72
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Я не знаю эту команду rename. Регулярное выражение выглядит как синтаксис sed. Если это так (как и во многих других формах регулярных выражений), оно состоит из 3 частей:

  • s на замену
  • все между первыми двумя косыми чертами (.*)(.*), чтобы указать, что соответствует
  • все, что находится между 2-й и 3-й косой чертой new$1$2, является заменой

$ означает только конец строки в первой части регулярного выражения. Во второй части $ номер относится к группам захвата, $1 — к первой группе, $2 — ко второй и т. д., причем $0 часто представляет собой весь соответствующий текст.

Вы правы, что .* жадный и повторять это бессмысленно. Возможно, между ними был \., и это была попытка захватить имя и расширение файла. Есть лучшие способы разбора имен файлов, например basename. Таким образом, вы можете упростить команду до rename -n 's/(.*)/new$1/' *

Вероятно, это скрипт переименования; это Перл.

Jim Davis 19.11.2022 20:30

На самом деле. Это не регулярное выражение, а оператор Perl. В данном случае это замещающий оператор (который представляет собой шаблон регулярного выражения, но включает его).

ikegami 19.11.2022 21:46

Спасибо за объяснение, я рад, что я не совсем сумасшедший!

Felthorn3 20.11.2022 14:57
Ответ принят как подходящий

Ты прав. (.*)(.*) смысла нет. Второй .* всегда будет соответствовать пустой строке.

Например, сопоставление с file,

  • первый .* будет соответствовать строке из 4 символов, начинающейся с позиции 0 (file), и
  • второй .* будет соответствовать строке из 0 символов, начиная с позиции 4 (пустая строка).

Вы можете упростить шаблон до

rename -n 's/(.*)/new$1/' *
rename -n 's/.*/new$&/' *
rename -n 's/^/new/' *
rename -n '$_ = "new$_"' *
rename -n '$_ = "new" . $_' *

Спасибо за это, это действительно помогло прояснить и то, что я не совсем сошел с ума!

Felthorn3 20.11.2022 14:57

Другие вопросы по теме