I have a directory full of images:
image0001.png image0002.png image0003.png ...
And I would like a one-liner to rename them to (say).
0001.png 0002.png 0003.png ...
How do I do this?
The zsh shell has a powerful batch rename command called
First you need to enable the
zmv command as follows (this can go into your
The basic syntax is
zmv PATTERN REPLACEMENT. The pattern is a shell glob expression. Parts of the pattern can be surrounded by parentheses. The replacement text can contain
$2, etc. to refer to the Nth parenthesised group in the pattern. For example:
zmv 'image(*.png)' '$1'
You can also ask zsh to automatically define
$2, etc. to match the wildcard characters in the pattern:
zmv -w 'image*.png' '$1.png'
I normally use the nice and simple mmv (man page) utility for this usecase:
$ mmv "image*.png" "#1.png"
will perform your task.
#1 in the target pattern will be substituted with whatever matches the wildcard in the source pattern. This also works for several wildcards and can be used for example to change the order of parts of filenames. You can also easily do more complicated things like converting lower case to upper case letters.
Make sure to protect the patterns from the shell by quoting.
renameutils opens an editor showing a list of filenames with two colums, separated by a tab. Each row shows one of the filenames, the same in both columns. The right column is representing the new names of the files.
To make changes, edit the names on the right side. In this example,
:%s/... or visual block mode are helpful.
$ qmv *.png
image0001.png image0001.png image0002.png image0002.png image0003.png image0003.png ~ ~ ~ ~ "/tmp/user/1000/qmvxWyVMs" 3L, 93C
Edit names in right column:
image prefix from all lines using visual block mode)
image0001.png 0001.png image0002.png 0002.png image0003.png 0003.png ~ ~ ~ ~ :wq
Log of renaming:
image0001.png -> 0001.png image0002.png -> 0002.png image0003.png -> 0003.png
apt-get install renameutils)
easy recurse selecting image*png files, and assumes no need to deal with newline in file names
find . -name "image*.png" | while read f; do mv -v "$f" "$(echo "$f" | sed -e 's/^\.\/image//' - )"; done
Safe, can deal with spaces, new lines, backslashes and anything else:
find . -name "image*.png" | while IFS= read -r f; do mv -v "$f" "$(echo "$f" | sed -e 's/^\.\/image//' - )"; done
Reading names from
find . -maxdepth 1 -type f -name 'image*png' | while IFS= read -r f; do mv -v "$f" "$(echo "$f" | sed -e 's/^\.\/image//' - )" done
Reading names from a file
while IFS= read -r f; do mv -v "$f" "$(echo "$f"|sed -e 's/^\.\/image//' - )"; done < flist
For Windows and linux, this Perl script will do; in this case:
$ rnm -l 's/^image//' '*.png'
The script could run recursively under directories and even prepending a count to all of them:
$ rnm -r 's/^/$counter./' '/\.png$/'
UTF-8 chars are also correctly treated, both in Windows and linux.
Try brename (https://github.com/shenwei356/brename), a practical cross-platform command-line tool for safely batch renaming files/directories via regular expression (supporting Windows, Linux and OS X) .
Linux has a variety of batch file renaming options but I didn’t see any short-comings in brename that jumped out at me.
find ./ -name "*.html" -exec CMD.
$ brename -f .png -p image [INFO] checking: [ ok ] 'image0001.png' -> '0001.png' [INFO] checking: [ ok ] 'image0002.png' -> '0002.png' [INFO] checking: [ ok ] 'image0003.png' -> '0003.png' [INFO] 3 path(s) to be renamed [INFO] renamed: 'image0001.png' -> '0001.png' [INFO] renamed: 'image0002.png' -> '0002.png' [INFO] renamed: 'image0003.png' -> '0003.png' [INFO] 3 path(s) renamed
Thank you for your interest in this question.
Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).
Would you like to answer one of these unanswered questions instead?