Pattern based, batch file rename in terminal
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/' {} \;
Related videos on Youtube
![Unamata Sanatarai](https://i.stack.imgur.com/S8ArV.jpg?s=256&g=1)
Unamata Sanatarai
Updated on September 18, 2022Comments
-
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?
-
ccpizza almost 8 yearsA failsafe regex-based python version which works recursively on all subfolders: stackoverflow.com/a/39698169/191246
-
-
wjandrea over 6 yearsNote 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 over 5 yearsThere's documentation for the
-iname
,-type
, and-exec
flags at manpages.ubuntu.com/manpages/bionic/man1/find.1.html#expression. (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 over 5 yearsIn 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. over 5 yearsWould you also be able to suggest a way to have this command work recursively in all subdirectories?
-
Alex Che over 5 yearsYour link points to another
rename
, which has formatrename from to file
and does not support regular expressions. Actually, my Linux distribution (Cent OS 7) has exactly that version. -
jave.web over 4 yearsFor 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 over 2 yearsapparently, my
rename from util-linux 2.37.2
on Ubuntu 21.04 does not support this