In 2008 I wrote a Python script to clean these files off my disks, and posted it in Italian. Rereading it for this English version, I found a bug: it never deleted a single .DS_Store. So here is the script again, fixed and in Python 3.

What these files are

Thumbs.db is the thumbnail cache Windows XP wrote in every folder you opened with the thumbnail view. Since Vista, Windows keeps thumbnails in a central cache in your profile, but Vista and Windows 7 still wrote Thumbs.db on network shares.

.DS_Store is what the Finder on macOS writes in every folder it opens: icon positions, view settings, window size. My 2008 post said it was a folder. It’s a file, and that was the bug: the old script looked for directories named .DS_Store, so it found none.

Both are harmless on the machine that made them. They get annoying when they end up in shared folders, USB drives, zip files and git repositories, where the other operating system shows them as junk.

The script

It walks a folder recursively and prints every Thumbs.db and .DS_Store it finds. Add --delete and it removes them too.

python
import argparse
from pathlib import Path

JUNK = {"thumbs.db", ".ds_store"}  # lowercase: Windows names are case-insensitive


def find_junk(root):
    for path in Path(root).rglob("*"):
        if path.name.lower() in JUNK and path.is_file():
            yield path


def main():
    parser = argparse.ArgumentParser(description="Find Thumbs.db and .DS_Store files.")
    parser.add_argument("root", help="folder to scan, recursively")
    parser.add_argument("--delete", action="store_true", help="delete them (default: only list)")
    args = parser.parse_args()

    for path in find_junk(args.root):
        print(path)
        if args.delete:
            path.unlink()


if __name__ == "__main__":
    main()

Run it once to see what it would delete, then again with --delete:

sh
python3 clean_junk.py ~/Shared
python3 clean_junk.py ~/Shared --delete

Compared to the 2008 version:

  • it checks files, not directories, so .DS_Store files are actually found;
  • names match case-insensitively, since Windows doesn’t care about case and you’ll find thumbs.db too;
  • listing is the default and deleting needs an explicit flag, instead of a second argument where any typo meant “just print”;
  • it uses pathlib and argparse, and runs on Python 3 (the old one used the Python 2 print statement).

Without Python

A reader pointed out in the comments that you don’t need a script for this. On Windows, from the folder you want to clean:

bat
del /S /F /A:H Thumbs.db

On macOS or Linux:

sh
find . -name .DS_Store -type f -delete

I still prefer the script when I’m cleaning a disk shared between the two, since it does both in one pass and shows the list first. If you want a bigger cleaner, another reader suggested BleachBit, which also happens to be written in Python.

Stop them from coming back

On a Mac you can tell Finder not to write .DS_Store files on network shares. Apple documents it in its SMB browsing article:

sh
defaults write com.apple.desktopservices DSDontWriteNetworkStores -bool TRUE

Log out and back in for it to take effect. For git repositories, add both names to your global gitignore and they never get committed again:

sh
printf '.DS_Store\nThumbs.db\n' >> ~/.gitignore_global
git config --global core.excludesFile ~/.gitignore_global