0

I have the following bash script, which iterates through all the images in a directory and attempts to determine the date and time it was created using exif. If the exif information is not available, it asks the user if it should use the image's last modified date instead. If the user declines, the image should be skipped:

for file in *.jpg; do
    if datetime="$(exif --debug --machine-readable --tag=DateTimeOriginal "$file" 2>&1)"; then
        datetime="${datetime##*$'\n'}"
    else
        datetime="$(stat --format=%y "$file")"
        datetime="${datetime%\.*}"

        echo "Warning: $file does not contain tag DateTimeOriginal"
        echo "Last modified date is $datetime - use it instead?"

        select yn in "Yes" "No"; do
            case "$yn" in
                Yes)
                    echo "Info: using last modified date for $file"
                    break
                    ;;
                No)
                    echo "Info: $file skipped - not using last modified date"
                    break
                    continue
                    ;;
            esac
        done
    fi

    echo "Renaming $file..."
done

The problem is even if the user declines the last line is still reached (i.e., "Renaming $file..." is printed to stdout). I think this is because the break prevents the continue from being reached. I tried flipping these two statements, but this results in an infinite loop:

                No)
                    echo "Info: $file skipped - not using last modified date"
                    continue
                    break
                    ;;

Hopefully it is clear what I'm trying to do.

EDIT

I found something that works, but let me know if there's a better way:

for file in *.jpg; do
    answer=

    if datetime="$(exif --debug --machine-readable --tag=DateTimeOriginal "$file" 2>&1)"; then
        datetime="${datetime##*$'\n'}"
    else
        datetime="$(stat --format=%y "$file")"
        datetime="${datetime%\.*}"

        echo "Warning: $file does not contain tag DateTimeOriginal"
        echo "Last modified date is $datetime - use it instead?"

        option1="Use last modified date"
        option2="Skip file"

        select answer in "$option1" "$option2"; do
            case "$answer" in
                "$option1"|"$option2")
                    break
                    ;;
            esac
        done

        if [ "$answer" = "$option2" ]; then
            echo "Info: $file skipped - not using last modified date"
            continue
        fi
    fi

    echo "Renaming $file..."
done

1 Answer 1

1

Edit: you can try this one:

for file in *.jpg; do
    if datetime="$(exif --debug --machine-readable  --tag=DateTimeOriginal "$file" 2>&1)"; then
        datetime="${datetime##*$'\n'}"
    else
        datetime="$(stat --format=%y "$file")"
        datetime="${datetime%\.*}"

        echo "Warning: $file does not contain tag DateTimeOriginal"
        echo "Last modified date is $datetime - use it instead?"

        select yn in "Yes" "No"; do
            case "$yn" in
                Yes)
                    echo "Info: using last modified date for $file"
                    break
                    ;;
                No)
                    echo "Info: $file skipped - not using last modified date"
                    break && continue
                    ;;
            esac
        done

    fi
   echo "Renaming $file..."
done
3
  • This has the same problem - continue is never reached. Also, if the first condition passes, "Renaming $file..." is never reached either. Dec 26, 2015 at 1:34
  • ok , you can try your original code , but this time the break and continue should not be on separate lines , instead , it should be : break && continue.
    – Ijaz Ahmad
    Dec 26, 2015 at 12:18
  • also note that you can try levels with break and continue such as break 2 , or continue 2 for outer loop.
    – Ijaz Ahmad
    Dec 26, 2015 at 12:23

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .