Reputation: 776
I am writing a short script: User chooses a folder with photos and then these photos are sorted by date of modification and renamed with pattern "PhotoX.jpg", where X is is number from 1 to total number of photos. When I execute this script first time everything is fine. The problem is, that when I try to execute this script again, on the same files, then Photo11.jpg disappeas and I don't know why. Here is code:
DIRECTORY=`zenity --file-selection --title="Wybierz miejsce docelowe" --directory`
FILES=()
eval "ls -r -path $DIRECTORY/ -t > temp.txt"
COUNTER=$(wc -l < "temp.txt")
eval mapfile -t FILES < "temp.txt"
eval "cd $DIRECTORY"
COUNTER=$((COUNTER-1))
for ((i=1;i<$COUNTER;i++))
do
eval "mv ${FILES[$i-1]} Photo$i.jpg"
done
eval "cd"
eval "rm temp.txt"
In all files, exept for Photo11, i get information in terminal, that PhotoX.jpg
and PhotoX.jpg
are the same files.
Upvotes: 0
Views: 54
Reputation: 295288
The code given is broken enough that it's not worth debugging -- better to rewrite.
To robustly prevent the number of output files from being less than the number of input files when input and output names can overlap, it's necessary to split the renaming into two parts: From the original name to a temporary name, and from the temporary name to the output name.
#!/bin/bash
# prompt for a directory via zenity only if not passed in on the environment
[[ -d $directory ]] || {
directory=$(zenity --file-selection --title="Wybierz miejsce docelowe" --directory)
}
tempnames=( )
# Move files to unique destination names, prefixed with intended final name
counter=1
while IFS= read -r -d ' ' _ && IFS= read -r -d '' filename; do # read time into _
destname="${directory}/Photo${counter}.jpg"
[[ $filename = "$destname" ]] && continue # skip files with correct names already
tempname=$(mktemp -- "$destname.XXXXXX") || continue # generate a unique dest name
mv -- "$filename" "$tempname" || { # and rename to that...
rm -f -- "$tempname" # ...deleting the tempfile and skipping the
continue # input file if the rename somehow fails.
}
tempnames+=( "$tempname" ) # ...keeping a log of what it was
(( counter++ )) # finally, increment our counter.
done < <(find "$directory" -type f -printf '%T@ %p\0' | sort -zn)
# Move from temporary names to real ones
for tempname in "${tempnames[@]}"; do
mv "$tempname" "${tempname%.*}"
done
See BashFAQ #3 to grok how we're combining GNU find
and GNU sort
to get a stream of files sorted by modification time.
Upvotes: 3