Search code examples
regexzsh

How to rename a file using regex capture group in Linux?


I want to rename a_1.0.tgz to b_1.0.tgz, since 1.0 may be changed to any version number, how can I achieve that?

For example, I can use mv a*.tgz b.tgz if I don't need to keep the version number.


Solution

  • zsh comes with the utility zmv, which is intended for exactly that. While zmv does not support regex, it does provide capture groups for filename generation patterns (aka globbing).

    First, you might need to enable zmv. This can be done by adding the following to your ~/.zshrc:

    autoload -Uz zmv
    

    You can then use it like this:

    zmv 'a_(*)' 'b_$1'
    

    This will rename any file matching a_* so, that a_ is replaced by b_. If you want to be less general, you can of course adjust the pattern:

    • to rename only .tgz files:

      zmv 'a_(*.tgz)' 'b_$1'
      
    • to rename only .tgz files while changing the extension to .tar.gz

      zmv 'a_(*).tgz' 'b_$1.tar.gz'
      
    • to only rename a_1.0.tgz:

      zmv 'a_(1.0.tgz)' 'b_$1'
      

    To be on the save side, you can run zmv with the option -n first. This will only print, what would happen, but not actually change anything. For more information have a look at the man zshcontrib.