Search code examples
bashperlrenamepcre

Regular expressions, capture groups, and the dollar sign


Reading a book about bash and it was introducing regular expressions(I'm pretty new to them) with an example:

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

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

There wasn't really a breakdown provided with this example, unfortunately. I kind of get what capture groups are and that .* is greedy and will match all characters but I'm uncertain as to why two capture groups are needed. Also, I get that $ represents the end of the line but am unsure of what $1$2 is actually doing here. Appreciate any insight provided.

Attempted to research capture groups and the $ for some similar examples with explanations but came up short.


Solution

  • You are correct. (.*)(.*) makes no sense. The second .* will always match the empty string.

    For example, matching against file,

    • the first .* will match the 4 character string starting at position 0 (file), and
    • the second .* will match the 0 character string starting at position 4 (empty string).

    You could simplify the pattern to

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