Every developer has that moment: you're doing the same tedious task for the third time this week, and you think "I should automate this." Then you spend 30 minutes writing a script, use it once, and forget about it.
Here are 5 Python scripts I actually keep in my ~/bin directory and use daily. No pip install required — they all use Python's standard library.
1. Downloads Folder Organizer
If your Downloads folder looks anything like mine (thousands of files, no structure), this one script saves more time than any other tool I've built:
#!/usr/bin/env python3
"""Organize downloads folder by file type."""
import os, shutil
from pathlib import Path
DOWNLOADS = Path.home() / 'Downloads'
CATEGORIES = {
'Images': ['.jpg', '.jpeg', '.png', '.gif', '.svg', '.webp'],
'Documents': ['.pdf', '.docx', '.doc', '.txt', '.md', '.csv', '.xlsx'],
'Archives': ['.zip', '.tar', '.gz', '.rar', '.7z'],
'Code': ['.py', '.js', '.ts', '.html', '.css', '.json', '.yaml', '.toml'],
'Videos': ['.mp4', '.mov', '.avi', '.mkv'],
'Audio': ['.mp3', '.wav', '.flac', '.m4a'],
}
for item in DOWNLOADS.iterdir():
if item.is_file():
ext = item.suffix.lower()
moved = False
for folder, exts in CATEGORIES.items():
if ext in exts:
target = DOWNLOADS / folder
target.mkdir(exist_ok=True)
shutil.move(str(item), str(target / item.name))
moved = True
break
if not moved:
target = DOWNLOADS / 'Other'
target.mkdir(exist_ok=True)
shutil.move(str(item), str(target / item.name))
Run it as a cron job once a day and your Downloads folder stays clean forever.
2. CSV Merger for Reporting
When you export data from multiple sources and need to join them into one file:
#!/usr/bin/env python3
"""Merge multiple CSV files into one, keeping headers from first file only."""
import csv, sys, os
from pathlib import Path
def merge_csv(input_dir, output_file):
files = list(Path(input_dir).glob('*.csv'))
if not files:
print('No CSV files found')
return
with open(output_file, 'w', newline='') as out:
writer = None
for i, f in enumerate(files):
with open(f) as inf:
reader = csv.reader(inf)
header = next(reader)
if i == 0:
writer = csv.writer(out)
writer.writerow(header)
for row in reader:
writer.writerow(row)
print(f'Merged {len(files)} files into {output_file}')
if __name__ == '__main__':
merge_csv(sys.argv[1] if len(sys.argv) > 1 else '.', 'merged_output.csv')
3. Find and Replace Across Files
Need to update an API endpoint URL across 50 files? This is faster than any GUI tool:
#!/usr/bin/env python3
"""Find and replace text across multiple files."""
import os, sys
from pathlib import Path
def find_replace(directory, find_text, replace_text, extensions=None):
count = 0
for path in Path(directory).rglob('*'):
if path.is_file():
if extensions and path.suffix not in extensions:
continue
try:
content = path.read_text(encoding='utf-8')
if find_text in content:
path.write_text(content.replace(find_text, replace_text))
count += 1
print(f'Updated: {path}')
except (UnicodeDecodeError, PermissionError):
continue
print(f'Updated {count} files')
if __name__ == '__main__':
find_replace(sys.argv[1], sys.argv[2], sys.argv[3])
4. Disk Usage Analyzer
Built-in tools like du are powerful but hard to parse. This gives you a sorted, human-readable breakdown:
#!/usr/bin/env python3
"""Show top disk usage directories."""
import os, sys
from pathlib import Path
def get_size(path):
total = 0
try:
for entry in os.scandir(path):
if entry.is_file():
total += entry.stat().st_size
elif entry.is_dir():
total += get_size(entry.path)
except PermissionError:
pass
return total
def human(size):
for unit in ['B', 'KB', 'MB', 'GB']:
if size < 1024:
return f'{size:.1f} {unit}'
size /= 1024
return f'{size:.1f} TB'
target = sys.argv[1] if len(sys.argv) > 1 else '.'
sizes = []
with os.scandir(target) as it:
for entry in it:
if entry.is_dir():
size = get_size(entry.path)
sizes.append((size, entry.name))
sizes.sort(reverse=True)
for size, name in sizes[:10]:
print(f'{human(size):>10} {name}')
5. Git Branch Cleaner
After months of development, your local git branches pile up. This script cleans merged branches safely:
#!/usr/bin/env python3
"""Delete local git branches merged into main/master."""
import subprocess, sys
def run(cmd):
return subprocess.run(cmd, shell=True, capture_output=True, text=True)
# Find default branch
for branch in ['main', 'master']:
result = run(f'git rev-parse --verify {branch}')
if result.returncode == 0:
default = branch
break
else:
print('No main/master branch found')
sys.exit(1)
# List merged branches
result = run(f'git branch --merged {default}')
branches = [b.strip() for b in result.stdout.split('\n')
if b.strip() and not b.startswith('*') and b.strip() != default]
if not branches:
print('No stale branches to clean')
sys.exit(0)
print(f'Deleting {len(branches)} stale branches...')
for b in branches:
run(f'git branch -d {b}')
print(f' Deleted: {b}')
The Complete Collection
These 5 scripts are part of a larger collection I packaged up — 50 Python Automation Scripts covering file operations, data processing, web scraping, system admin, and dev productivity. Each script is standalone, zero-dependency, and copy-paste ready.
→ 50 Python Automation Scripts — Copy-Paste Ready Tools ($4.99)
Every script includes error handling, docstrings with usage examples, and an MIT license so you can use them in commercial projects. Python 3.8+, no pip install needed.
Kai Thorne writes about Python, automation, and developer productivity. Follow for more practical scripts you can actually use.
Top comments (0)