0

I am attempting to rename all files (.jpg,.jpeg,.mov,etc) in parent directory and all subdirectories to date_time_7digitnumber without changing the file extension. The below script accomplishes this task but it runs numerous times, changing what was already correct. Here is the complete script. Any help would be greatly appreciated!

System: MacOS Monterey v12.5 Homebrew Installed with coreutils for gdate usage

#!/usr/bin/env bash

clear

RED='\033[0;31m'
NC='\033[0m'

shopt -s globstar nocaseglob nocasematch nullglob

echo
echo
echo -e "${RED}**********         Your current directory path is " $PWD "             **********${NC}"


read -p "

**********           This function is going to rename all media files with          ********** 

**********                            Date-Time-7digit number                       **********


**********                       !!THIS ACTION CAN NOT BE UNDONE!!                  **********

**********               !!MAKE SURE TO CHANGE TO THE CORRECT DIRECTORY!!           **********

      
      *** ARE YOU ABSOLUTELY SURE YOU ARE IN THE CORRECT DIRECTORY AND WISH TO PROCEED? ***

        
                                            [Y]es or [N]o  "  -n 1 -r



echo    # (optional) move to a new line
if [[ $REPLY =~ ^[Yy]$ ]]

then

n=1
for f in * ; do
   find . -type f -print0 |
        while IFS= read -r -d '' f ; do
            dd=$(dirname "$f")
            ext=${f##*.}
            new=$(gdate -r "$f" +"%Y%m%d_%H%M%S")-$(printf "%07d%s" "$n")
            mv -vn "$f" "$dd"/"$new"."$ext" ; ((n++))
        done 
      
done  

Echo

Echo Renaming Process Complete!

Echo

afplay /System/Library/Sounds/Ping.aiff

afplay /System/Library/Sounds/Ping.aiff

afplay /System/Library/Sounds/Ping.aiff

fi

enter image description here

2
  • 1
    You have too much going on there. Globbing and find are redundant operations. Cleaning up your code, something like this should work: ix.io/47Ee. However, I assumed gdate can be replaced with date.
    – r_31415
    Commented Aug 15, 2022 at 2:24
  • It's because the way you use find inside for loop. Drop the for loop and it should do it.
    – annahri
    Commented Aug 15, 2022 at 13:39

1 Answer 1

0

I would replace the following section of your code,

n=1
for f in * ; do
   find . -type f -print0 |
        while IFS= read -r -d '' f ; do
            dd=$(dirname "$f")
            ext=${f##*.}
            new=$(gdate -r "$f" +"%Y%m%d_%H%M%S")-$(printf "%07d%s" "$n")
            mv -vn "$f" "$dd"/"$new"."$ext" ; ((n++))
        done 
      
done

by this code:

DATE=$(date -r "$f" +"%Y%m%d_%H%M%S")
LOG="RENAME_${DATE}.log"    ; rm -f "${LOG}"
ERR="RENAME_${DATE}.err"    ; rm -f "${ERR}"

n=1
for f in *
do
    dd=$(dirname "$f")
    ext=${f##*.}
    new=${DATE}-$(printf "%07d%s" "$n")
        
    COM="mv -vn '${f}' '${dd}/${new}.${ext}'"

    ### LOG Everything for potential recovery action or later troubleshooting search
    echo "${new}.${ext}|${f}|${PWD}|${COM}"
    ${COM} >&2 2>>"${ERR}"

    ((n++))
done  >"${LOG}" 2>&1

The purpose being the following:

  • the find action serves no purpose (unless you expected to go looking for sub-directory content, but you seemed to suggest such would not be the case),
  • the while serves no purpose with the find command gone,
  • reduce the work of calculating a date at each file (not necessary, unless you wanted to use to name the file based on its actual creation date), and
  • log before information for possible later investigations, and
  • log specific errors reported for the actual rename actions.

I would further comment that the risk associated with running the script with a simple yes response (sometimes we press the wrong key) would dictate the need to specify the directory's full-path as a command line parameter, thereby imposing the conscious need to have specified the intended "target" before the script initiates, as well as making it a tool which could then be called from a batch to work on a potential list of directories.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.