Question

I have 100s of subdirectories with 100s of files each who's filename (may) have numbers that need to be zero-padded.

I have found solutions for padding 1 number in filenames of the form:

    file1.txt -> file001.txt

But my situation is little more complex.

But in my case:

  • Filenames may have more than 1 number. All numbers must be padded.
  • Filenames may contain spaces.
  • Some filenames may not need any padding.

For example:

    "v10 file p1-2.txt"      -> "v010 file p001-002.txt"
    1.txt                    -> 001.txt
    "v011 file p001-002.txt" -> do nothing
    002.txt                  -> do nothing

So i need a "generic" bash loop to rename (if needed) all the files in the subdirectories with all its numbers zero padded but I am unsure of how to accomplish this.

I have not found any help on padding more that one number in a filename.

Thank you in advance.

Edit 1:

In reality, this is part of a larger script that does more processing, but as of now this is what I am using:

#!/bin/bash
mkdir ../test
SAVEIFS=$IFS
IFS=$(echo -en "\n\b")
for file in ./*
do
    cd ${file}
    ls *
    # do something
    # mv "something" to ../../test
    cd ..
done
IFS=$SAVEIFS

exit 0

The problem is that "do something" will not perform as intended if there are unpadded filenames (the result ends up with shuffled pages).

There are many solutions for the simple padding situation, right now I was looking at:

Solution form http://www.walkingrandomly.com/?p=2850

#!/bin/bash
# zeropad.sh
num=`expr match "$1" '[^0-9]*\([0-9]\+\).*'`
paddednum=`printf "%03d" $num`
echo ${1/$num/$paddednum}

and then inserting this before "do something"

for i in *.*; do mv $i `./zeropad.sh $i`; done

But I am aware that this solution might not be perfect and might not be extended for my purpose.

Edit 2:

The solution to my problem was:

perl -pe 's{([^0-9]+)?([0-9]+)}{$1 . sprintf("%03s",$2)}ge'
Was it helpful?

Solution

Adapting the sed solution from the question I linked to your case can be done like this:

sed -r ':r;s/([^0-9]|^)([0-9]{1,2})([^0-9]|$)/\10\2\3/g;tr' file_list
v010 Cover.jpg
v010 End.jpg
v010 p000.jpg
v010 p010-011.jpg
v010 p012-013.jpg
v010 p014-015.jpg
v010 p016-017.jpg
v010 p018-019.jpg
v010 p019;TN.jpg
v010 p001.jpg
v010 p002-003.jpg
v010 p004-005.jpg
v010 p006-007.jpg
v010 p008-009.jpg
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top