Pattern based, batch file rename in terminal

84,655

Solution 1

The solution to the above example, using rename:

rename -v -n 's/file_\d{1,3}/upl/' file_*.png

Usage:

rename [options] [Perl regex search/replace expression] [files]

From man rename:

   -v, --verbose
           Verbose: print names of files successfully renamed.
   -n, --no-act
           No Action: show what files would have been renamed.

rename MAY take regex as the arguments.

What we are looking at is the content between the single quotes '. You can place regex separated by /.

Formula: s/(1)/(2)/ where (1) = search pattern, and (2) = replace pattern.

So, familiarize youself with regex, and enjoy pattern based batch file renaming!

Solution 2

This can be done with little magic of bash parameter expansion!

for f in file_[0-9]*_*; do mv $f upl_${f#file_[0-9]*_}; done

file_[0-9]*_*; - First pattern is used to go trough all files that begin with 'file_anynumber_'
${f#file_[0-9]*_} - The second pattern file_[0-9]*_ is used in parameter expansion which tells bash to remove 'file_anynumber_' from the begging of the string.

For more information on Parameter expansion:

man bash

Solution 3

if files are in severals directories, use rename after a find like :

find -iname file_*.png -type f -exec rename -n 's/file_[0-9]{3}(.*\.png)/upl$1/' {} \;

the -n after rename is to test, remove it to proceed !-)

like this, you associate find and rename power.

Personally, I used it to rename sources header .h to .hpp

find -iname *.h -type f -exec rename 's/(.*\.)h/$1hpp/' {} \;
Share:
84,655

Related videos on Youtube

Unamata Sanatarai
Author by

Unamata Sanatarai

Updated on September 18, 2022

Comments

  • Unamata Sanatarai
    Unamata Sanatarai almost 2 years

    I need to rename the following:

    file_001_loremipsum.png
    file_002_dolor.png
    file_003_sit.png
    file_004_amet.png
    file_105_randomness.png
    

    into

    upl_loremipsum.png
    upl_dolor.png
    upl_sit.png
    upl_amet.png
    upl_randomness.png
    

    How do I make it happen with just one simple line of terminal command?

  • wjandrea
    wjandrea over 6 years
    Note that this uses globs, not regex, so [0-9]* will match one digit followed by any string. There's probably a better way to match just numbers, but I can't think of anything succinct.
  • Patrick Dark
    Patrick Dark over 5 years
    There's documentation for the -iname, -type, and -exec flags at manpages.ubuntu.com/manpages/bionic/man1/find.1.html#express‌​ion. (find --help isn't particularly helpful for this command.) TL;DR: -iname matches a pattern case‐insensitively; -type f matches “regular files”; and -exec executes an expression until it encounters a ; (semicolon) character.
  • Patrick Dark
    Patrick Dark over 5 years
    In Ubuntu 18.10, the --no-act flag is --nono instead. This answer could also be a bit more explicit: [files] refers to an initial pattern matching files in the current directory that one wants to potentially rename (e.g., * matches everything, but only in the current directory).
  • Francesco D.M.
    Francesco D.M. over 5 years
    Would you also be able to suggest a way to have this command work recursively in all subdirectories?
  • Alex Che
    Alex Che over 5 years
    Your link points to another rename, which has format rename from to file and does not support regular expressions. Actually, my Linux distribution (Cent OS 7) has exactly that version.
  • jave.web
    jave.web over 4 years
    For my sys no-action is "--nono" : rename --verbose --nono 's/ /_/' * => show final names of files after space would be replaced with underscore in current directory, for all files (*)
  • m02ph3u5
    m02ph3u5 over 2 years
    apparently, my rename from util-linux 2.37.2 on Ubuntu 21.04 does not support this