How to batch rename files via Terminal using the file’s date as filename

bashfilerenameterminal

I have a bunch of photos and videos from different sources and want to normalize the file names using Terminal. I looked at a bunch of different tools from NameChanger to Automator and Finder itself. NameChanger does not allow more than one action at a time and Finder and Automator won't allow me to set the date format with a format string.

I've been playing around with a few bash functions and found that

stat -f "%Sm" -t "%Y-%m-%d %H.%M.%S" file.ext

produces the date time format I'm after.

Yet I found that

for file in *.*
do
    mv "$file" echo stat -f "%Sm" -t "%Y-%m-%d %H.%M.%S" "$file"
done

returns

-bash: syntax error near unexpected token `done'

I'm not really proficient with bash scripting so excuse any incompetence in the examples above.

What I want to do is remove all of the base name of the file (everything before .jpg) and replace it with the date and time format I got from stat earlier.

For example:

20160708_151344000_iOS.jpg   --> 2016-07-08 15.13.44.jpg
WP_20140915_02_03_15_Raw.jpg --> 2014-09-15 02.03.15.jpg

How do I need to do this?

Best Answer

for f in *.*; do 
    echo mv "$f" "$(stat -f '%Sm' -t '%Y-%m-%d %H.%M.%S' "$f").${f##*.}"
done

Or as a one-liner:

for f in *.*; do echo mv "$f" "$(stat -f '%Sm' -t '%Y-%m-%d %H.%M.%S' "$f").${f##*.}"; done

In either case, remove the echo command after testing.

The ${f##*.} portion of the command get the extension of $f so you can use the glob *.* vs. using an extension in the for f in, i.e. for f in *.* vs. for f in *.jpg