Seudonym
Seudonym

Reputation: 562

Add character to file name if duplicate when moving with bash

I currently use a bash script and PDFgrep to rename files to a certain structure. However, in order to stop overriding if the new file has a duplicate name, I want to add a number at the end of the name. Keep in mind that there may be 3 or 4 duplicate names. What's the best way to do this?

#!/bin/bash
if [ $# -ne 1 ]; then
   echo Usage: Renamer file
   exit 1
fi
f="$1"
id1=$(pdfgrep -m 1 -i "MR# :  " "$f" | grep -oE "[M][0-9][0-9]+") || continue
id2=$(pdfgrep -m 1 -i "Visit#" "$f" | grep -oE "[V][0-9][0-9]+") || continue
{ read today; read dob; read dop; } < <(pdfgrep -i " " "$f" | grep -oE "[0-9][0-9]/[0-9][0-9]/[0-9][0-9][0-9][0-9]")
dobsi=$(echo $dob | sed -e 's/\//-/g')
dopsi=$(echo $dop | sed -e 's/\//-/g')
mv -- "$f" "${id1}_${id2}_$(printf "$dobsi")_$(printf "$dopsi")_1.pdf"

Upvotes: 0

Views: 567

Answers (1)

Barmar
Barmar

Reputation: 780798

Use a loop that checks if the destination filename exists, and increments a counter if it does. Replace the mv line with this:

prefix="${id1}_{id2}_${dob}_${dop}"
counter=0
while true
do
    if [ "$counter" -ne 0 ]
    then target="${prefix}_${counter}.pdf"
    else target="${prefix}.pdf"
    fi
    if [ ! -e "$target" ]
    then
        mv -- "$f" "$target"
        break
    fi
    ((counter++))
done

Note that this suffers from a TOCTTOU problem, if the duplicate file is created between the ! -f "$target" test and the mv. I thought it would be possible to replace the existence check with using mv -n; but while this won't overwrite the file, it still treats the mv as successful, so you can't test the result to see if you need to increment the counter.

Upvotes: 2

Related Questions