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 files in the following format: x1 x2 ... x10 x11 ... x101 ...

I want to rename these files, so they all have the same name length: x001 x002 ... x010 ...

I can do this with files, that don't have the non-numeric prefix (just using sort -n followed by a while read x;), but sort doesn't recognize the numeric value, when it's not on the beginning of the file-name.

share|improve this question
add comment

3 Answers

up vote 5 down vote accepted

You can try sorting the files using the v (version) option of ls e.g. ls -1v. Or you can use numeric sort with x as the delimiter: ls | sort -n -t 'x' +1

But you don't have to sort the files to rename them. You can just look at the length of the file name and pad it with zeros if necessary. Here is a small script which does that:

prefix=x
maxLength=4

for file in ${prefix}*
do
 if [ ${#file} -lt $maxLength ]
 then
     newFile=$file
     while [ ${#newFile} -lt $maxLength ]
     do
       newFile=${newFile/$prefix/${prefix}0}
     done   
     mv $file $newFile
 fi
done
share|improve this answer
add comment

Are you sure you need to sort them first?

m=0
for f in x*; do
  [ "${#f}" -gt "$m" ] &&
    m=${#f}
done

for f in x*; do
  echo mv -- "$f" "${f%${f#?}}$( printf '%0.*d' $(( m - 1 )) "${f#?}" )"
done 

If your printf implementation doesn't support the syntax above, use printf "%0.$(( m - 1 ))d" "${f#?}".

Remove echo when satisfied.

share|improve this answer
add comment

You need rename, while there are similar tools, which could serve you too:

touch x1 x2 x10 x11 x101 
ls ; rename 's/x/x0/' x[0-9] 

x1 x10 x101 x11 x2

ls ; rename 's/x/x0/' x[0-9][0-9] 

x01 x02 x10 x101 x11

ls

x001 x002 x010 x011 x101

'rename' is part of some perl package, if you need to install it, at least available for Linux.

Without rename, there is a similar solution with a loop:

rm * 
touch x1 x2 x10 x11 x101
for f in  x[0-9] ; do mv $f ${f/x/x0}; done 
for f in  x[0-9][0-9] ; do mv $f ${f/x/x0}; done ; ls 

x001 x002 x010 x011 x101

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.