4

I've got bunch of files with ill-formed numbering:

prefix-#.ext | for files with number 1-9 prefix-##.ext | for files with number 10-99 prefix-###.ext | for files with number 100-999 

Due to further processing I need all of their names to be in format: prefix-###.ext. Is there any easy way to do that?

3 Answers 3

5

On Debian, Ubuntu and derivatives, you can use the rename Perl script:

rename 's/(?<=-)([0-9]+)/sprintf "%03d", $1/e' prefix-*.ext 

Some systems may have this command installed as prename or perl-rename. Note that this is not the rename utility from the util-linux suite which does not provide an easy way to do this.

In zsh, you can use zmv to rename and the l parameter expansion flag to pad with zeroes.

autoload -U zmv zmv '(prefix-)(*)(.ext)' '$1${(l:3::0:)2}$3' 

You can also do this with a plain shell loop. Shells don't have nice string manipulation constructs; one way to pad with zeroes is to add 1000 and strip off the leading 1.

for x in prefix-*.ext; do n=${x%.ext}; n=${x##*-}; n=$((n+1000)) mv "$x" "${x%-*.ext}${n#1}${x##*-}" done 

Another way is to call the printf utility.

for x in prefix-*.ext; do n=${x%.ext}; n=${x##*-} mv "$x" "${x%-*.ext}$(printf %03d "$n")${x##*-}" done 
1
  • The first example is beautiful one-liner. However, on ArchLinux it's called perl-rename, not just rename or prename. Commented Mar 22, 2015 at 16:47
1

Perhaps something like this (untested)

for n in *.ext; do echo mv "$n" \ "prefix-$(printf %03d "$(basename ${n#prefix-} .ext)").ext" done 

Remove the echo to do the actual renaming.

Note: you have to be in the directory where the files are for this method to work; dealing with pathnames that contain a directory part is more complicated.

2
  • Yep, it works. If've found perl-rename, but I don't know how to make ### numbers from variable length numbers. Commented Mar 13, 2015 at 11:58
  • you don't, instead you find numbers that are too short. and add zeroes, Commented Dec 15, 2019 at 4:10
1
for file in prefix-*.ext do num=`echo $file | sed 's/prefix-\(.*\).ext/\1/'` [ $num -lt 100 ] && mv $file prefix-`printf "%03d" ${num}`.ext done 

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.