Bulk Rename Photos

Rename photos based on the date they were taken

Problem

I take a lot of photos on my phone and I want to quickly rename them all into a standard format.

Solution

for file in $(ls *.jpg); do mv -n $file $(exiftool -d "%Y%m%d_%H%M%S" -DateTimeOriginal -S -s $file).jpg; done

The script above will rename all images in the current directory to the time they were taken.

The resulting files will look like this:

20220514_155042.jpg
20220508_163754.jpg
20220507_114358.jpg

This does not work with files that have a space in their name.

The -n in the move command prevents it from overwriting existing files. This is important if there are multiple photos taken at the same time.

Details

At a high level, this command will iterate over the results of the ls file and apply a mv command to each one. The output file name of the mv command is based on the output of the exiftool command.

The exiftool application is essential to read the photo metadata and extract the original time a photo was taken. This will not work without it installed.

Here is the command broken down into pieces:

  • for file in $(ls *.jpg);
    • Get the path to all files in the current directory that end with .jpg
  • exiftool -d "%Y%m%d_%H%M%S" -DateTimeOriginal -S -s $file
    • Extract the time a photo was taken from the file metadata and print it in a custom format
  • mv -n $file $(exiftool -d "%Y%m%d_%H%M%S" -DateTimeOriginal -S -s $file).jpg;
    • Rename the original file to a new name based on the time the photo was taken

You can quickly tweak the script in the following ways:

  • Update the ls *.jpg command and the .jpg at the end of the target file name to handle another file format
  • The ls *.jpg command can be changed to apply a filter (e.g. ls my_prefix*.jpg)
  • The file format can be tweaked in the mv command
    • %Y%m%d_%H%M%S determines how the "date taken" value is converted to a string
    • You can add custom prefixes or suffixes by adding text around the $(...) section