Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Correcting file numbers using bash

I have a bunch of file names in a folder like this:

test_07_ds.csv
test_08_ds.csv
test_09_ds.csv
test_10_ds.csv
...

I want to decrease the number of every file, so that these become:

test_01_ds.csv
test_02_ds.csv
test_03_ds.csv
test_04_ds.csv
...

Here's what I came up with:

for i in $1/*; do
    n=${i//[^0-9]/};
    n2=`expr $n - 6`;
    if [ $n2 -lt 10 ]; then
        n2="0"$n2;
    fi
    n3=`echo $i | sed -r "s/[0-9]+/$n2/"`
    echo $n3;
    cp $i "fix/$n3";
done;

Is there a cleaner way of doing this?

like image 794
xyz Avatar asked Dec 21 '25 15:12

xyz


1 Answers

This might help:

shopt -s extglob
for i in test_{07..10}_ds.csv; do
    IFS=_ read s m e <<<"$i";         # echo "Start=$s Middle=$m End=$e"
    n=${m#+(0)}                       # Remove leading zeros to
                                      # avoid interpretation as octal number.
    n=$((n-6))                        # Subtract 6.
    n=$(printf '%02d' "$n")           # Format `n` with a leading 0.
    # comment out the next echo to actually execute the copy.
    echo \
        cp "$i" "fix/${s}_${n}_${e}";
done;

Or collapsing it all together

#!/bin/bash
shopt -s extglob
for i in ${1:-.}/*; do                    # $1 will default to pwd `.`
    IFS=_ read s m e <<<"$i";             # echo "Start=$s Middle=$m End=$e"
    n=$(printf '%02d' "$((${m#+(0)}-6))")
    cp "$i" "fix/${s}_${n}_${e}";
done;