Search code examples
regexunixbatch-rename

Regex - Renaming files with a prefix/suffix


Command below is from this answer: https://stackoverflow.com/a/208220/3470343

The command adds the word new. as a prefix. That's understood.

rename 's/(.*)$/new.$1/' original.filename

However, I'd like to ask why the open and close brackets are required here:

(.*)

And also why is $1 the variable which stores the original file name, why can't I do the the same with following (where i have replaced $1 with $2):

rename 's/(.*)$/new.$2/' original.filename

I'm still relatively new to bash, so help would be greatly appreciated.


Solution

  • First off, (.*)$ is what is known as a regular expression (or regex). Regular expressions are used to match text based on some rules.

    For example, .* matches zero or more characters. $ matches the end of the line. Because regular expressions by default are greedy, .*$ matches the whole line (although, precisely because regexes are greedy, $ is superfluous).

    However, I'd like to ask why the open and close brackets are required here: (.*)

    The round brackets denote a group. Groups are used to "save" the contents of the matched text, so that you can use it later.

    And also why is $1 the variable which stores the original file name, why can't I do the the same with following (where I have replaced $1 with $2): ...

    In the case of rename(1), the first group is stored in $1, the second group is stored in $2 and so on. For example, the following regular expression:

    (a)(b)(c)
    

    stores a single a into $1, a single b into $2 and so on.

    There you have only one group, therefore you must use $1. Tokens like $2, $3, ... will be empty.

    Last but not least, you could use a shorter, equivalent command:

     rename 's/^/new./'
    

    Here ^ denotes the start of the string.