Reputation: 87
My files have the following pattern:
a0015_random_name.txt
a0016_some_completely_different_name.txt
a0017_and_so_on.txt
...
I would like to rename only the numbering using the shell, so that they are going two numbers down:
a0015_random_name.txt ---> a0013_random_name.txt
a0016_some_completely_different_name.txt ---> a0014_some_completely_different_name.txt
a0017_and_so_on.txt ---> a0015_and_so_on.txt
I've tried already this:
let n=15; for i in *.txt; do let n=n-2; b=`printf a00`$n'*'.txt; echo "mv $i $b"; done
(I use echo first, in order to see what would happen)
but this gave me:
mv a0015_random_name.txt a0013*.txt
mv a0016_some_completely_different_name.txt a0014*.txt
mv a0017_and_so_on.txt a0015*.txt
Also I've tried to find the command, which would set the rest of the name right, but I couldn't find it. Does someone know it, or have a better idea how to do this?
Upvotes: 1
Views: 61
Reputation: 9321
Your code is almost correct. Try this:
let n=15; for i in *.txt; do let n=n-2; b=`echo $i | sed "s/a[0-9]*/a$n/g`; echo "mv $i $b"; done
Better yet, to make it more robust, use the following modification:
let n=15; for i in *.txt; do let t=n-2; let n=n+1; b=`echo $i | sed "s/a00$n/a00$t/g`; echo "mv $i $b"; done
Upvotes: 4
Reputation: 95252
If you have the Perl rename.pl
script, this is a one-liner:
rename 's/\d+/sprintf "%0${\(length $&)}d", $&-2/e' *.txt
Otherwise, it's a bit wordier. Here's one way:
for f in *.txt; do
number=$(expr "$f" : '^[^0-9]*\([0-9]*\)') # extract the first number from the filename
prefix=${f%%$number*} # remember the part before
suffix=${f#*$number} # and after the number
let n=10#$number-2 # subtract 2
nf=$(printf "%s%0${#number}d%s" \
"$prefix" "$n" "$suffix") # build new filename
echo "mv '$f' '$nf'" # echo the rename command
# mv "$f" "$nf" # uncomment to actually do the rename
done
Note the 10#
on the let
line - that forces the number to be interpreted in base 10 even if it has leading zeroes, which would otherwise cause it to be interpreted in base 8. Also, the %0${#number}d
format tells printf
to format the new number with enough leading zeroes to be the same length as the original number.
On your example, the above script produces this output:
mv 'a0015_random_name.txt' 'a0013_random_name.txt'
mv 'a0016_some_completely_different_name.txt' 'a0014_some_completely_different_name.txt'
mv 'a0017_and_so_on.txt' 'a0015_and_so_on.txt'
Upvotes: 2