Is there an easy way to do this for files in a particular directory - to have their names be renamed to the file timestamp, with seconds level precision


For example, suppose a (Mac 10.14.15) directory has the following files, where the notation below shows original file name and file creation time. (But, to be clear, we are working from the Mac file directory, and not from the luxury of just parsing thru a text file.) The filenames are uuid 36 character names:

35eafb32-8005-11e9-bc42-526af7764f64.png 09:35:01
419f0eb4-8005-11e9-bc42-526af7764f64.png 09:35:11
43249984-8005-11e9-bc42-526af7764f64.png 21:02:03

Suppose I want to rename the files based on (original creation) timestamp, but the filename of course has to be in an acceptable format:


(In the actual case, the directory has 2000+ files. If it matters, they are transported from an iPhone X app I made - through iTunes file sharing. The file creation date and time shows up correctly on Mac when transferred.)

  • Are all 2000+ files in the same directory? Are there any subdirectories in the directory that contains the 2000+ files? Is prepend in prepend-09_35_01.png the original filename? I also said, "Also, as you have the automator tag, show us your workflow too.", yet you did not comment nor have you said what type of solution you'd prefer, bash script to use in Terminal only or an Automator workflow, etc. It's really a shame you just couldn't' be explicit and specific! Commented May 26, 2019 at 23:26
  • tbh i haven't been able to get anything to work in automator for this. maybe terminal batch scripts might be an easier approach? and yes, all files in a directory.
    – ina
    Commented May 27, 2019 at 1:58
  • 1
    I posted an answer (at this point 2 hours ago), are you saying it didn't work for you? Commented May 27, 2019 at 2:13
  • yes thanks for your thorough answer! learned a lot!!
    – ina
    Commented May 27, 2019 at 5:46

1 Answer 1


If all the files are in the same directory, then in Terminal, changed directory, e.g.
cd /path/to/directory and then use the following compound command:

for f in *.*; do echo mv -n "$f" "${f%.*}-$(stat -f'%SB' -t "%H_%M_%S" "$f").${f##*.}"; done

Note: There is an intensional echo command that is there for you to test with, and it will only print out the mv command for you to see that it's the outcome you wish. You can then run it again removing just echo from the compound command to actually rename the files as desired via the mv command.


$ touch 35eafb32-8005-11e9-bc42-526af7764f64.png 419f0eb4-8005-11e9-bc42-526af7764f64.png 43249984-8005-11e9-bc42-526af7764f64.png
$ ls -1
$ for f in *.*; do echo mv -n "$f" "${f%.*}-$(stat -f'%SB' -t "%H_%M_%S" "$f").${f##*.}"; done
mv -n 35eafb32-8005-11e9-bc42-526af7764f64.png 35eafb32-8005-11e9-bc42-526af7764f64-19_56_35.png
mv -n 419f0eb4-8005-11e9-bc42-526af7764f64.png 419f0eb4-8005-11e9-bc42-526af7764f64-19_56_35.png
mv -n 43249984-8005-11e9-bc42-526af7764f64.png 43249984-8005-11e9-bc42-526af7764f64-19_56_35.png
$ for f in *.*; do mv -n "$f" "${f%.*}-$(stat -f'%SB' -t "%H_%M_%S" "$f").${f##*.}"; done
$ ls -1

Understanding the bash compound command:

  • for f in *.*; do ...; done    For every file in the current dir do the following command(s) to them.
  • echo    Print what follows. (Must be removed for the mv command to actually work.)
  • mv -n source target    Move files, do not overwrite an existing file, filename, new filename.
    • "$f"    The source filename.
    • "${f%.*}-$(stat -f'%SB' -t "%H_%M_%S" "$f").${f##*.}"    The target filename.
    • ${f%.*}    Name portion of the filename without the extension. See Parameter Expansion in the bash man page.
    • -    The HYPHEN-MINUS character.
    • $(...)    Command Substitution, allows the output of a command to replace the command name.
    • stat -f'%SB' -t "%H_%M_%S" "$f"
    • stat    Display file status. See its man page for more details.
    • -f'%SB'    −f format    Display information using the specified format. See the FORMATS section for a description of valid formats. In this case %SB represents string output of the birth time of the inode. (The time the file was created.)
    • -t "%H_%M_%S"    −t timefmt    Display timestamps using the specified format. This format is passed directly to strftime(3). In this case it represents the hour, a LOW LINE character (AKA underscore), the minute, a LOW LINE character, the second.
    • %H    Is replaced by the hour as a decimal number (00-23).
    • %M    Is replaced by the minute as a decimal number (00-59).
    • %S    Is replaced by the second as a decimal number (00-60).
    • "$f"    The source filename.
    • .    The FULL STOP character. (AKA dot or period.)
    • ${f##*.}    The extension portion of the filename. See Parameter Expansion in the bash man page.

Note that the upper case character names are that which show in Character Viewer on a US English install of macOS.

  • very thorough explanation. for f in *.*; do mv -n "$f" "prepend-$(stat -f'%SB' -t "%H_%M_%S" "$f").${f##*.}"; done worked! thanks !
    – ina
    Commented May 27, 2019 at 5:44

You must log in to answer this question.

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