Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

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?

share|improve this question
5  
This is one of the top Unix command line FAQs, and I can't find it on this site already, so should we make this Community Wiki? –  Gilles Aug 24 '10 at 0:08
3  
I don't see why. It's a specific question with a verifiable answer. –  Internet man Aug 24 '10 at 0:45
2  
If you're running X it doesn't get much easier than thunar -B *.png for thunar's bulk-rename gui tool. –  dotjoe Aug 25 '10 at 21:26
add comment

9 Answers 9

up vote 22 down vote accepted

If you are using bash:

for f in *.png; do mv "$f" "${f#image}"; done
share|improve this answer
4  
You're missing double quotes around the variable substitutions, so your command will fail if any of the file names contains whitespace or \\[*?. The loop body should be mv "$f" "${f#image}";. –  Gilles Aug 24 '10 at 7:18
1  
@Giles you are right. That's a good upgrade. I only addressed the problem presented. –  W_Whalley Aug 24 '10 at 10:00
1  
This is one of the parameter substitution methods shown in Mendel Coopers Advanced Bash-scripting guide tldp.org/LDP/abs/html –  W_Whalley Aug 25 '10 at 14:15
add comment

ls *png | while read -r f; do f2="`echo $f | sed -e's/image//'`"; mv $f $f2; done

share|improve this answer
    
Something's not right: "mv: missing destination file operand after 'image0001.png'" –  Internet man Aug 24 '10 at 0:06
2  
There are many problems with your code. Parsing the output of ls is just calling for trouble. read should be read -r. all variable substitutions should be within double quotes. –  Gilles Aug 24 '10 at 0:20
    
You could write this more effectively as for f in *png; do f2="$(echo "$f" | sed -e 's/image//')"; mv "$f" "$f2"; done. Parsing ls is neither necessary nor a good idea. –  kojiro Feb 10 at 4:24
add comment

This has worked. Perl's rename:

rename -v 's/image//' *.png
share|improve this answer
2  
you really should explain that this is a perl programm that might have to be installed and that it takes regular expressions as the argument. –  hop Aug 24 '10 at 0:30
    
Ah, I was not aware of that. I'll give credit to the canonical answer, when I identify it :) –  Internet man Aug 24 '10 at 0:33
1  
This rename program came from a Perl examples distribution. Debian and Ubuntu ship it as /usr/bin/rename. Other Unix variants may not provide it, or may provide a completely different /usr/bin/rename. –  Gilles Aug 24 '10 at 7:17
    
On some systems it may be called prename. There is also more than one version of it, regardless of how it's named. –  Dennis Williamson Aug 26 '10 at 0:13
add comment

zmv

The zsh shell has a powerful batch rename command called zmv.

First you need to enable the zmv command as follows (this can go into your ~/.zshrc).

autoload zmv

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 $1, $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 $1, $2, etc. to match the wildcard characters in the pattern:

zmv -w 'image*.png' '$1.png'
share|improve this answer
1  
sweeeeeeeeeeeeeeeeeet. yet another reason i should be learning zsh. –  ixtmixilix Oct 11 '11 at 13:16
1  
@ixtmixilix what's to learn? Just start using it and perhaps add prezto (github.com/sorin-ionescu/prezto) for some extra awesomeness. –  Gerry Aug 15 '12 at 8:09
add comment

I like Perl so:

perl -nlE '$old=$_; s/image//; qx(mv $old $_)'

You can also use the same pattern for other tasks like copying the files to another directory:

perl -nlE '$old=$_; s(image)(/path/to/new/dir/); qx(mv $old $_)'
share|improve this answer
add comment

I normally use the nice and simple mmv utility for this usecase:

$ mmv "image*.png" "#1.png"

will perform your task.

The #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.

share|improve this answer
    
Thanks for pointing out this utility. I found it in Debian, Ubuntu and Cygwin repositories. I had trouble with the man page, but found some web pages and this Stack Overflow question that helped explain how you were using it. stackoverflow.com/questions/417916/how-to-do-a-mass-rename –  W_Whalley Aug 25 '10 at 16:12
    
Thanks, I added some more information to the answer to make it clearer. –  Marcel Stimberg Aug 25 '10 at 19:28
add comment

POSIX sh for loop

Uses sed to rename

for i in image*jpg
do 
  mv -v "$i" "$(echo "$i" | sed -e 's/^\.\/image//' - )"
done
share|improve this answer
add comment

POSIX sh using a while loop

Reading names from find command.

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
share|improve this answer
add comment

recursive

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
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.