Identify Unused Image Files in a Code Project

Searching for image files

I wrote a script to list (and optionally delete) the image files it finds in a directory that are not referenced any where.  I specified a single sub-directory at a time. If you do the entire project it may take long to complete.

#!/bin/bash

PROJECT_DIR="$PWD"
IMAGE_DIR="$PWD"

DELETE_FLAG=false

# Check for -d (delete) flag
if [[ $1 == "-d" ]]; then
    DELETE_FLAG=true
fi

# Find all image files
find $IMAGE_DIR -type f \( -iname \*.png -o -iname \*.jpg -o -iname \*.jpeg -o -iname \*.gif -o -iname \*.webp -o -iname \*.svg -o -iname \*.ico \) | while read img_file; do
    # Extract the basename of the image file
    img_basename=$(basename "$img_file")
    
    # Search for it in the project, excluding .zip files and .git directories
    result=$(grep -ril --exclude=*.zip --exclude-dir=.git "$img_basename" "$PROJECT_DIR")
    
    # If not found, print it or delete it based on flag
    if [ -z "$result" ]; then
        echo "Unused image: $img_file"
        if $DELETE_FLAG; then
            rm "$img_file"
            echo "Deleted: $img_file"
        fi
    fi
done

Be sure to edit the code to include the image file types that you want to target. Make the file executable before trying to use it:

chmod +x find_unused_images.sh

Run the script (without deletion)

./find_unused_images.sh

To run the script with the delete functionality:

./find_unused_images.sh -d

Find unused images in a project

In an early version, my script was leaving behind files that appeared to be completely unreferenced in the code base (I checked manually by searching the project via IDE). To troubleshoot, I ran grep from the command line:

grep -ril "experienceLogo2.png" "$PWD"

It turned out that those files were referenced in a zip file and in git objects (and therefore considered not unused). I fixed this bug by adding the flags –exclude=*.zip –exclude-dir=.git to my grep command in find_unused_images.sh.

grep to find a file reference within a directory
I had lots of unused stock images and old designs that felt good to purge. Now with generative image AI, I know I could create assets easily as I need them in the future.

I used this script during a project to upgrade my website to use next generation file formats. If you liked this post, read another one where I discuss managing graphic assets for a web project.

Update

Identify any unused files in a code project

This code can be changed to search for any kind of file. Here’s an updated version I used to see if some old Bootstrap files were being used any where:

#!/bin/bash

PROJECT_DIR="$PWD"
FILE_DIR="$PWD/css"

DELETE_FLAG=false

# Check for -d (delete) flag
if [[ $1 == "-d" ]]; then
    DELETE_FLAG=true
fi

# Find all image files
# find $FILE_DIR -type f \( -iname \*.png -o -iname \*.jpg -o -iname \*.jpeg -o -iname \*.gif -o -iname \*.webp -o -iname \*.svg -o -iname \*.ico \) | while read my_file; do
find $FILE_DIR -type f \( -iname \*.css -o -iname \*.js \) | while read my_file; do
    # Extract the basename of the image file
    file_basename=$(basename "$my_file")
    
    # Search for it in the project, excluding .zip files and .git directories and .xml directories
    result=$(grep -ril --exclude=*.zip --exclude-dir=.git --exclude=*.xml "$file_basename" "$PROJECT_DIR")
    
    # If not found, print it or delete it based on flag
    if [ -z "$result" ]; then
        echo "Unused file: $my_file"
        if $DELETE_FLAG; then
            rm "$my_file"
            echo "Deleted: $my_file"
        fi
    fi
done

This didn’t work perfectly. I had to add an exclusion condition for .xml files because my WordPress blog archive files were being highlighted in the search. (EOD, I ended up zipping the few .xml archive files anyway. I also keep them on an S3 bucket, but I enjoy redundancy.)

The file name “bootstrap.css” was being found in its own file.

Bootstrap source code

This, at least, gave me enough confidence to just delete the files manually. I can’t call this a perfect tool (and I don’t think it would scale well), but it is a utility for a practical use-case.

I saw other examples of it acting funny. For instance, I had an old stock photo file named ‘5.jpg’. It was coming up as being used in the project because, for some reason, that string was found in another image file – ‘jimmy.webp’.

using grep to search image file names