Reputation: 23
I have a directory containing .jpg files, currently named photo-1.jpg
, photo-2.jpg
etc. There are about 20,000 of these files, sequentially numbered.
Sometimes I delete some of these files, which creates gaps in the file naming convention.
Can you guys help me with a bash script that would sequentially rename all the files in the directory to eliminate the gaps? I have found many posts about renaming files and tried a bunch of things, but can't quite get exactly what I'm looking for.
For example:
photo-1.jpg
photo-2.jpg
photo-3.jpg
Delete photo-2.jpg
photo-1.jpg
photo-3.jpg
run script to sequentially rename all files
photo-1.jpg
photo-2.jpg
done
Upvotes: 1
Views: 299
Reputation: 7801
With find
and sort
.
First check the output of
find directory -type f -name '*.jpg' | sort -nk2 -t-
If the output is not what you expected it to be, meaning the order of sorting is not correct, then It might have something to do with your locale
. Add the LC_ALL=C
before the sort.
find directory -type f -name '*.jpg' | LC_ALL=C sort -nk2 -t-
Redirect it to a file so it can be recorded, add a | tee output.txt
after the sort
Add the LC_ALL=C
before the sort
in the code below if it is needed.
#!/bin/sh
counter=1
find directory -type f -name '*.jpg' |
sort -nk2 -t- | while read -r file; do
ext=${file##*[0-9]} filename=${file%-*}
[ ! -e "$filename-$counter$ext" ] &&
echo mv -v "$file" "$filename-$counter$ext"
counter=$((counter+1))
done # 2>&1 | tee log.txt
directory
to the actual name of your directory that contains the files that you need to rename.sort
has the -V
flag/option then that should work too.sort -nk2 -t-
The -n
means numerically sort. -k2
means the second field and the -t-
means the delimiter/separator is a dash -
, can be written as -t -
, caveat, if the directory name has a dash -
as well, sorting failure is expected. Adjust the value of -k
and it should work.ext=${file##*[0-9]}
is a Parameter Expansion, will remain only the .jpg
filename=${file%-*}
also a Parameter Expansion, will remain only the photo
plus the directory name before it.[ ! -e "$filename-$counter$ext" ]
will trigger the mv
ONLY if the file does not exists.#
after the done
Upvotes: 1