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 of files such as:

file.1.png
file.2.png
…
file.10.png
…
file.1000.png
file.1001.png
…

How can I pad the number to 4 digits? It should end up like this:

file.0001.png
file.0002.png
…
file.0010.png
…
file.1000.png
file.1001.png
…
share|improve this question

5 Answers 5

This will also work:

for f in *.png; do
    int=`basename $f .png | cut -d '.' -f 2`
    new_name=`printf "file.%0.4i.png\n" $int`
    [ ! -f $new_name ] && mv $f $new_name
done
share|improve this answer
1  
+1 since this handle the not asked for file.11001.png as well as fixing the described examples. –  Johan Sep 26 '11 at 15:26

Try the following:

for f in *.png
do
   foo='0000'${f#file.} #remove "file." and prepend 0000
   foo=${foo:(-8)} #last eight characters
   echo mv $f file.$foo   
done

Remove the echo if you are happy with the output.

share|improve this answer
    
-1 If you have 5 or more digits like file.11001.png, then that file will become file.1001.png since all filename gets 4 digits with this solution. frogstarr78:s example with printf is a better. –  Johan Sep 26 '11 at 15:29
1  
@Johan the question asks "How can I pad the number to 4 digits?" That's what I answered. It's not supposed to work for 5 or more digits. –  dogbane Sep 26 '11 at 17:01
    
Your answer does kind of answer the question, but in the question is also a couple of ... after file.1001.png that implies that there could be higher numbers. If you had a note about this limit then I would not have downvoted. –  Johan Sep 26 '11 at 18:45

A simple trick if you want a simple, portable script is to start counting at 10001 and strip the initial digit.

for x in file.*.png; do
  n=${x%.*}; n=${n##*.}
  n=$((n + 10000))
  mv "$x" "${x%.*.*}.${n#1}.${x##*.}"
done

With zsh, using zmv and the l parameter expansion flag:

setopt extended_glob
autoload zmv
zmv '(file).([0-9]##).(png)' '$1.${(l:4::0:)2}.$3'
share|improve this answer
    
+1 for using zmv –  dom0 Aug 1 '13 at 20:14

If you have the rename command from the Perl package (as opposed to the one from the util-linux package):

rename 's/(\d+)/sprintf"%04d",$1/ge' file.*.png

Alternative based on glenn jackman' comment, which suggests a portable solution involving Perl. As Perl has its own rename function, there is no more need for the external mv:

ls -1 file.*.png | perl -ne 'chomp;($n=$_)=~s/(\d+)/sprintf"%04d",$1/ge;rename$_,$n'

That code is easier to enhance to reproduce the extras added by the rename external command: skip if the new file name is identical with the old one and skip if there is already a file with the new name:

ls -1 | perl -ne 'chomp;($n=$_)=~s/(\d+)/sprintf"%04d",$1/ge;rename$_,$n if$_ ne$n&&!-f$n'

With some adaptation, a loop-less solution can be achieved even with Sed:

ls -1 file.*.png | sed -r '/[0-9]{4}/d;h;:p;/[0-9]{4}/!s/([0-9]{1,3})/0\1/;tp;G;s/(.+)\n(.+)/mv \2 \1/' | sh
share|improve this answer
1  
and if you don't have rename, mv "$f" "$(perl -pe 's/(\d+)/sprintf"%04d",$1/ge' <<< "$f")" (assuming you use bash) –  glenn jackman Sep 26 '11 at 13:39
    
@glennjackman Yes, in this case probably will do the job. But will give error messages for all files where the number already has 4 digits and will overwrite existing files. –  manatwork Sep 26 '11 at 14:09

There are already quite a few answers here, but I thought I'd throw up a simple one

rename 'file.' 'file.000' file.?.png
rename 'file.' 'file.00' file.??.png
rename 'file.' 'file.0' file.???.png

The rename utility comes standard on every distro I know of. Its not as fancy as some of the other solutions here, but simple is easy to remember.

The first line takes file.1.png and converts it to file.0001.png.
The second converts file.10.png to file.0010.png, and the third does file.100.png to file.0100.png.
The 4 digit ones are already done.

share|improve this answer

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.