Читая книгу о 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. Цените любую предоставленную информацию.
Попытка исследовать группы захвата и $ для некоторых подобных примеров с пояснениями, но не удалась.
@ Felthorn3 - Что это за книга?
@JimDavis, это «Learn Bash the Hard Way» Яна Миелла.
Я не знаю эту команду rename
. Регулярное выражение выглядит как синтаксис sed
. Если это так (как и во многих других формах регулярных выражений), оно состоит из 3 частей:
s
на замену(.*)(.*)
, чтобы указать, что соответствуетnew$1$2
, является заменой$
означает только конец строки в первой части регулярного выражения. Во второй части $
номер относится к группам захвата, $1
— к первой группе, $2
— ко второй и т. д., причем $0
часто представляет собой весь соответствующий текст.
Вы правы, что .*
жадный и повторять это бессмысленно. Возможно, между ними был \.
, и это была попытка захватить имя и расширение файла. Есть лучшие способы разбора имен файлов, например basename
. Таким образом, вы можете упростить команду до rename -n 's/(.*)/new$1/' *
Вероятно, это скрипт переименования; это Перл.
На самом деле. Это не регулярное выражение, а оператор Perl. В данном случае это замещающий оператор (который представляет собой шаблон регулярного выражения, но включает его).
Спасибо за объяснение, я рад, что я не совсем сумасшедший!
Ты прав. (.*)(.*)
смысла нет. Второй .*
всегда будет соответствовать пустой строке.
Например, сопоставление с 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" . $_' *
Спасибо за это, это действительно помогло прояснить и то, что я не совсем сошел с ума!
Важно понимать, что это регулярное выражение будет обрабатываться командой
rename
, а не самим bash, и его синтаксис может несколько отличаться от регулярных выражений bash (очевидно, что bash не помещает свои группы захвата в$1
,$2
, и т. д., но в${BASH_REMATCH[1]}
и т. д. Иgrep
, иsed
, иawk
, и т. д. все делают немного по-разному..