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.
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:
python3 clean_junk.py ~/Shared
python3 clean_junk.py ~/Shared --deleteCompared 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.dbtoo; - 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
printstatement).
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:
del /S /F /A:H Thumbs.dbOn macOS or Linux:
find . -name .DS_Store -type f -deleteI 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:
defaults write com.apple.desktopservices DSDontWriteNetworkStores -bool TRUELog 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:
printf '.DS_Store\nThumbs.db\n' >> ~/.gitignore_global
git config --global core.excludesFile ~/.gitignore_global