Rename files by incrementing a number within the filename
I think that it should do the work:
#!/bin/bash
NEWFILE=$1
for file in `ls|sort -g -r`
do
filename=$(basename "$file")
extension=${filename##*.}
filename=${filename%.*}
if [ $filename -ge $NEWFILE ]
then
mv "$file" "$(($filename + 1))".$extension
fi
done
Script takes one parameter - number of you new image.
PS. Put script in another directory than your images. In images directory there should be only images named in this way that you described.
This would be easier in zsh, where you can use
- the
On
glob qualifier to sort matches in decreasing order (andn
to use numerical order, in case the file names don't all have leading zeroes to the same width); - the
(l:WIDTH::FILLER:)
parameter expansion flag to pad all numbers to the same width (the width of the larger number).
break=$1 # the position at which you want to insert a file
setopt extended_glob
width=
for x in [0-9]*(nOn); do
n=${x%%[^0-9]*}
if ((n < break)); then break; fi
((++n))
[[ -n $width ]] || width=${#n}
mv $x ${(l:$width::0:)n}${x##${x%%[^0-9]*}}
done
In bash, here's a script that assumes files are padded to a fixed width (otherwise, the script won't rename the right files) and pads to a fixed width (which must be specified).
break=$1 # the position at which you want to insert a file
width=9999 # the number of digits to pad numbers to
files=([0-9]*)
for ((i=#((${#files}-1)); i>=0; --i)); do
n=${x%%[^0-9]*}
x=${files[$i]}
if ((n < break)); then continue; fi
n=$((n + 1 + width + 1)); n=${n#1}
mv -- "${files[$i]}" "$n${x##${x%%[^0-9]*}}"
done
There doesn't seem to be much recent interest in this question but, should someone stumble upon it, there are three issues here.
One is how to select files to rename based on semantic criteria (range is not lexical and cannot be specified by wildcards or even regular expressions-- automata theory says that this is more complex than an NFA).
The second is how to change a name by modifying a portion of it.
The third is how to avoid name collision.
A script in Bash and many other languages can do this specific transform, but most of us would rather not have to write a program every time we want to rename a bunch of files.
With my (free and open source) rene.py
you can do what you want but it takes two invocations to avoid the name collision problem.
- First
increments all names in the range, adding a prefix ofrene ?.*/#7-80 %?.* B
%
to avoid existing names. - Then
removes this prefix from those files that have it.rene %* *
I describe this at https://sourceforge.net/p/rene-file-renamer/discussion/examples/thread/f0fe8aa63c/