问题
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
回答1:
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
- Change the
directoryto the actual name of your directory that contains the files that you need to rename. - If your
sorthas the-Vflag/option then that should work too. sort -nk2 -t-The-nmeans numerically sort.-k2means 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-kand it should work.ext=${file##*[0-9]}is a Parameter Expansion, will remain only the.jpgfilename=${file%-*}also a Parameter Expansion, will remain only thephotoplus the directory name before it.[ ! -e "$filename-$counter$ext" ]will trigger themvONLY if the file does not exists.- If you want some record or log, remove the comment
#after thedone - Remove the echo if you think that the output is correct
来源:https://stackoverflow.com/questions/62181370/batch-rename-all-files-in-a-directory-to-basename-sequentialnumber-extention