惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

G
Google Developers Blog
Jina AI
Jina AI
大猫的无限游戏
大猫的无限游戏
Martin Fowler
Martin Fowler
博客园 - 司徒正美
云风的 BLOG
云风的 BLOG
C
Cybersecurity and Infrastructure Security Agency CISA
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
S
Securelist
S
Security Affairs
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
L
LINUX DO - 热门话题
博客园 - 三生石上(FineUI控件)
T
Threatpost
T
The Blog of Author Tim Ferriss
C
CERT Recently Published Vulnerability Notes
IT之家
IT之家
P
Palo Alto Networks Blog
Microsoft Azure Blog
Microsoft Azure Blog
Spread Privacy
Spread Privacy
Cyberwarzone
Cyberwarzone
腾讯CDC
L
LangChain Blog
Know Your Adversary
Know Your Adversary
C
CXSECURITY Database RSS Feed - CXSecurity.com
GbyAI
GbyAI
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
I
Intezer
T
Tor Project blog
AWS News Blog
AWS News Blog
T
Tenable Blog
NISL@THU
NISL@THU
Security Latest
Security Latest
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
H
Hackread – Cybersecurity News, Data Breaches, AI and More
人人都是产品经理
人人都是产品经理
MongoDB | Blog
MongoDB | Blog
MyScale Blog
MyScale Blog
D
DataBreaches.Net
Microsoft Security Blog
Microsoft Security Blog
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
量子位
美团技术团队
The Cloudflare Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
罗磊的独立博客
The GitHub Blog
The GitHub Blog
阮一峰的网络日志
阮一峰的网络日志
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Stack Overflow Blog
Stack Overflow Blog

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant Common SOC 2 Failures (Real World) Stop Vibe-Checking Your AI App: A Practical Guide to Evals How to Use SonarQube and SonarScanner Locally to Level Up Your Code Quality Your Next To-Do App Is Dead — I Replaced Mine with an OpenClaw AI Sign a Nostr event in 60 lines of Python using coincurve — no nostr-sdk, no nbxplorer, no rust toolchain ITGC Audit Explained Like You’re in Big 4 Patch Tuesday abril 2026: Microsoft parcha 163 vulnerabilidades y un zero-day en SharePoint Stop scraping everything: a better way to track competitor price changes Listing on MCPize + the Official MCP Registry while routing payments OUTSIDE the marketplace — how I kept 100% of my x402 revenue Building an AI-Powered Risk Intelligence System Using Serverless Architecture Why We Ripped Function Overloading Out of Our AI Toolchain Testing AI-Generated Code: How to Actually Know If It Works SaaS Churn Is Killing Your Business. Here Is What to Do About It (Without a Support Team) The Speed of AI Is No Longer Linear - And Self-Improving Models Are Why How to Implement RBAC for MCP Tools: A Practical Guide for Engineering Teams From Standard Quote to Persuasive Proposal: AI Automation for Arborists I built a CLI that scaffolds complete multi-tenant SaaS apps Axios CVE-2025–62718: The Silent SSRF Bug That Could Be Hiding in Your Node.js App Right Now The dashboard that ended our friendship Data Pipelines Explained Simply (and How to Build Them with Python) The Hidden Cost of AI Systems Nobody Talks About. undefined vs undeclared, and how typeof behaves Switching from file-based jobs to NATS/Kafka in Rust without changing code io_uring Adventures: Rust Servers That Love Syscalls Why Agentic AI is Killing the Traditional Database The POUR principles of web accessibility for developers and designers Quantum Neural Network 3D — A Deep Dive into Interactive WebGL Visualization How To Install Caveman In Codex On macOS And Windows Automation Pipeline Reliability: Why Your Workflow Breaks When Nobody Is Watching I Built an 'Open World' AI Coding Agent — It Works From ANY Folder From Freelancing to Product: A Tech Service Company's SaaS Transformation China's AI Giants: Adding Tencent Hunyuan & ByteDance Doubao to AI University (74 Providers) On the Vibe Coders and Their Lies clerk: Auto-Summarize Your Claude Code Sessions AI Weekly — 2026/04/10–04/17 | The Model Lockdown Is Here, but the Toolchain Is the Real Battleground AI 週報 — 2026/04/10–2026/04/17 模型封鎖潮來了,但工具鏈才是真戰場 Maybe this is how Open-Source apps are born... 🚀 Fine-Tune LLMs with LoRA and QLoRA: 2026 Guide tRPC v11 + Next.js App Router: End-to-End Type Safety Without the Boilerplate ShadCN UI in 2026: Why I Stopped Installing Component Libraries and Started Owning My Components SaaS Billing in React Server Components: Stripe + Supabase Without a Single `useEffect` Join our DEV Weekend Challenge — $1,000 in Prizes Across TEN winners! Submissions Due April 20 at 6:59 AM UTC. Implementing FSRS Spaced Repetition in Flutter + Supabase — Adding Memory Science to an AI Learning App "I Texted My Localhost From the Train — Claude Code Fixed the Bug Before I Got Home" I Built a Sales Prep AI and It Went Deeper Than Expected Design to Code #2: One JSON, Eleven Outputs Solving the 100M-Row Problem: A Summary Table Pattern for High-Volume Push Notification Logs Flutter Web With Wasm: What Actually Changes For Developers I Built 50 Royalty-Free Soundtracks for My Side Project in a Weekend Using AI Music Generation The Vibe Coding Security Checklist: 7 Things to Check Before You Ship Stop Letting Googlebot Guess Fix Your React App's SEO Right Desconstruindo o Streaming do LinkedIn: Como Criar um Engine de Extração de Vídeo de Alta Performance com HLS e FFmpeg (EDA Part-1) EDA (Exploratory Data Analysis) Explained With Real Life — Why Looking at Your Data Is the Most Important Step in Machine Learning Brand Relationship Management at Scale: Our 4-Touch Outreach System for 200+ Brands Why String.fromEnvironment() Might Return an Empty String in Dart JGuardrails 1.0.0 — Hardening Java LLM Apps Against Jailbreaks, Toxicity, and Prompt Injection Plan and Schedule a Full Week of Threads Content From One Claude Conversation Coding Cat Oran Ep3, Five Tables Changed Everything Updated: BFF Pattern I'm done watching freelancers get buried by 200 proposals. So I'm building the alternative. This is my first post BFS Algorithm in Java Step by Step Tutorial with Examples Tracking LLM Pricing Monthly: An Open Dataset for 22 AI Models How We Measure Content ROI on a Comparison Site: Revenue Attribution Without Perfect Data Introducing Nova AI Ops: The AI-Native Operating System for SRE Teams I built a free desktop video downloader for Windows — Grabbit How Talkie OCR Helps Vision-Impaired & Dyslexic Users Read the World Around Them VRCFaceTracking安装和iPhone面捕配置教程,有bug Even CrowdStrike Can't See Your Agents The Automation Gold Rush: What n8n Workflows and Claude Are Opening Up for Developers Right Now
Automate Your Boring File Tasks with Python: 5 Scripts You Can Use Today
smn729 · 2026-05-11 · via DEV Community

Let's be honest: most of the repetitive file operations we do every day don't require our attention. Renaming hundreds of files, cleaning messy CSVs, resizing images one by one — these tasks are necessary but mind-numbing.

I've been collecting and writing Python automation scripts for the past few years, and I want to share five that have saved me the most time. You can copy these directly, adapt them to your workflow, and start automating today.


Before We Start

You'll need Python 3.8+ installed. Each script below is a single file — no complex setup required. Just save it, install any dependencies, and run.

pip install pillow pandas  # for image and CSV scripts

Enter fullscreen mode Exit fullscreen mode


1. Smart File Organizer

This one is my most-used script. Your Downloads folder is probably a mess — mine definitely was. This script sorts files into folders by type or date.

#!/usr/bin/env python3
import os
import shutil
import argparse
from collections import defaultdict

FILE_CATEGORIES = {
    'Images': ['.jpg', '.jpeg', '.png', '.gif', '.webp', '.svg'],
    'Documents': ['.pdf', '.docx', '.txt', '.md', '.xlsx', '.pptx'],
    'Audio': ['.mp3', '.wav', '.flac', '.aac', '.m4a'],
    'Video': ['.mp4', '.mov', '.avi', '.mkv', '.webm'],
    'Archives': ['.zip', '.tar', '.gz', '.rar', '.7z'],
    'Code': ['.py', '.js', '.ts', '.html', '.css', '.json', '.yaml'],
}

def organize_by_type(source_dir, target_dir=None, dry_run=False):
    if not target_dir:
        target_dir = source_dir

    for filename in os.listdir(source_dir):
        filepath = os.path.join(source_dir, filename)
        if os.path.isfile(filepath):
            ext = os.path.splitext(filename)[1].lower()
            category = 'Other'
            for cat, exts in FILE_CATEGORIES.items():
                if ext in exts:
                    category = cat
                    break

            dest = os.path.join(target_dir, category)
            if dry_run:
                print(f'[DRY RUN] Would move: {filename} -> {category}/')
            else:
                os.makedirs(dest, exist_ok=True)
                shutil.move(filepath, os.path.join(dest, filename))
                print(f'Moved: {filename} -> {category}/')


if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Organize files by type')
    parser.add_argument('directory', help='Directory to organize')
    parser.add_argument('--dry-run', action='store_true', help='Preview only')
    args = parser.parse_args()
    organize_by_type(args.directory, dry_run=args.dry_run)

Enter fullscreen mode Exit fullscreen mode

Usage:

# Preview what would happen
python file-organizer.py ~/Downloads --dry-run

# Actually organize
python file-organizer.py ~/Downloads

Enter fullscreen mode Exit fullscreen mode


2. CSV Cleaner

CSV files from different sources are never consistent. Different separators, extra whitespace, missing values, duplicate rows — this script handles the common pain points.

#!/usr/bin/env python3
import csv
import sys
import argparse


def clean_csv(input_file, output_file, **options):
    with open(input_file, 'r', encoding='utf-8') as f:
        reader = csv.DictReader(f)
        rows = list(reader)
        fieldnames = reader.fieldnames

    cleaned = []
    seen = set()

    for row in rows:
        # Strip whitespace from all values
        if options.get('strip'):
            row = {k: v.strip() if isinstance(v, str) else v
                   for k, v in row.items()}

        # Remove empty rows
        if options.get('drop_empty'):
            if all(v == '' or v is None for v in row.values()):
                continue

        # Remove duplicates
        if options.get('drop_duplicates'):
            row_key = tuple(row.values())
            if row_key in seen:
                continue
            seen.add(row_key)

        # Fill missing values
        if options.get('fill'):
            row = {k: (v if v != '' else options['fill'])
                   for k, v in row.items()}

        cleaned.append(row)

    with open(output_file, 'w', encoding='utf-8', newline='') as f:
        writer = csv.DictWriter(f, fieldnames=fieldnames)
        writer.writeheader()
        writer.writerows(cleaned)

    print(f'Cleaned: {len(rows)} -> {len(cleaned)} rows')


if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Clean CSV files')
    parser.add_argument('input', help='Input CSV file')
    parser.add_argument('--output', '-o', default='cleaned.csv')
    parser.add_argument('--strip', action='store_true')
    parser.add_argument('--drop-duplicates', action='store_true')
    parser.add_argument('--drop-empty-rows', action='store_true')
    parser.add_argument('--fill', help='Fill missing values with this')
    args = parser.parse_args()
    clean_csv(args.input, args.output,
              strip=args.strip,
              drop_empty=args.drop_empty_rows,
              drop_duplicates=args.drop_duplicates,
              fill=args.fill)

Enter fullscreen mode Exit fullscreen mode

Usage:

python csv-cleaner.py messy_data.csv --strip --drop-duplicates --output clean.csv

Enter fullscreen mode Exit fullscreen mode


3. Batch Image Resizer

Need to resize 50 images for a website or social media post? Doing it manually in Photoshop is not the move.

#!/usr/bin/env python3
import os
from PIL import Image
import argparse


def resize_images(directory, max_width, output_format='webp', quality=85):
    for filename in os.listdir(directory):
        if not filename.lower().endswith(('.png', '.jpg', '.jpeg')):
            continue

        filepath = os.path.join(directory, filename)
        img = Image.open(filepath)

        # Calculate new height maintaining aspect ratio
        ratio = max_width / img.width
        new_size = (max_width, int(img.height * ratio))

        img_resized = img.resize(new_size, Image.LANCZOS)

        # Save in the chosen format
        new_name = os.path.splitext(filename)[0] + f'.{output_format}'
        output_path = os.path.join(directory, new_name)

        if output_format.lower() == 'webp':
            img_resized.save(output_path, 'WEBP', quality=quality)
        elif output_format.lower() == 'jpg':
            img_resized.save(output_path, 'JPEG', quality=quality)
        else:
            img_resized.save(output_path)

        print(f'Resized: {filename} -> {new_name} ({new_size[0]}x{new_size[1]})')


if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Batch resize images')
    parser.add_argument('directory', help='Directory with images')
    parser.add_argument('--max-width', type=int, default=1200)
    parser.add_argument('--format', default='webp', choices=['webp', 'jpg', 'png'])
    parser.add_argument('--quality', type=int, default=85)
    args = parser.parse_args()
    resize_images(args.directory, args.max_width, args.format, args.quality)

Enter fullscreen mode Exit fullscreen mode

Usage:

python image-resizer.py ./photos --max-width 800 --format webp --quality 90

Enter fullscreen mode Exit fullscreen mode


4. PDF Text Extractor

Need to pull text from multiple PDFs for analysis? This script handles it.

#!/usr/bin/env python3
import os
import json
import argparse

try:
    import PyPDF2
except ImportError:
    import subprocess
    subprocess.check_call(['pip', 'install', 'PyPDF2'])
    import PyPDF2


def extract_pdfs(directory, output_format='txt'):
    results = {}

    for filename in os.listdir(directory):
        if not filename.lower().endswith('.pdf'):
            continue

        filepath = os.path.join(directory, filename)
        text = []

        with open(filepath, 'rb') as f:
            reader = PyPDF2.PdfReader(f)
            for page_num in range(len(reader.pages)):
                page = reader.pages[page_num]
                extracted = page.extract_text()
                if extracted.strip():
                    text.append(f'--- Page {page_num + 1} ---\n{extracted}')

        results[filename] = '\n'.join(text)

    if output_format == 'json':
        output = json.dumps(results, indent=2, ensure_ascii=False)
        print(output)
    else:
        for pdf_name, content in results.items():
            print(f'\n{"="*60}')
            print(f'FILE: {pdf_name}')
            print(f'{"="*60}')
            print(content)


if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Extract text from PDFs')
    parser.add_argument('directory', help='Directory with PDF files')
    parser.add_argument('--format', choices=['txt', 'json'], default='txt')
    args = parser.parse_args()
    extract_pdfs(args.directory, args.format)

Enter fullscreen mode Exit fullscreen mode


5. Batch File Renamer

Renaming files one by one is maybe the single most tedious task in computing. This script gives you pattern-based renaming with a dry-run mode so you never accidentally destroy your file names.

#!/usr/bin/env python3
import os
import re
import argparse


def rename_files(directory, pattern, replacement, dry_run=False):
    for filename in os.listdir(directory):
        filepath = os.path.join(directory, filename)
        if not os.path.isfile(filepath):
            continue

        new_name = re.sub(pattern, replacement, filename)
        if new_name == filename:
            continue

        new_path = os.path.join(directory, new_name)
        if dry_run:
            print(f'[DRY RUN] {filename} -> {new_name}')
        else:
            os.rename(filepath, new_path)
            print(f'Renamed: {filename} -> {new_name}')


if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Batch rename files')
    parser.add_argument('directory', help='Target directory')
    parser.add_argument('--pattern', '-p', required=True, help='Regex pattern')
    parser.add_argument('--replace', '-r', required=True, help='Replacement')
    parser.add_argument('--dry-run', action='store_true', help='Preview')
    args = parser.parse_args()
    rename_files(args.directory, args.pattern, args.replace, args.dry_run)

Enter fullscreen mode Exit fullscreen mode

Usage:

# Replace spaces with underscores
python batch-renamer.py ./docs --pattern '\s+' --replace '_' --dry-run

# Remove "(1)" suffixes from duplicates  
python batch-renamer.py ./downloads --pattern '\((\d+)\)' --replace ''

Enter fullscreen mode Exit fullscreen mode


Putting It All Together

These scripts are intentionally simple — each one does one thing and does it well. Here are a few real workflows where I use them together:

Weekly photo processing:

# 1. Organize incoming photos
python file-organizer.py ~/CameraUploads --method date

# 2. Resize for web
python image-resizer.py ~/CameraUploads/2026-05 --max-width 1200 --format webp

# 3. Rename with consistent pattern
python batch-renamer.py ~/CameraUploads/2026-05 --pattern 'IMG_\d+' --replace 'vacation_'

Enter fullscreen mode Exit fullscreen mode

Data pipeline cleanup:

# 1. Extract data from PDF reports
python pdf-extractor.py ~/Reports --format json > raw_data.json

# 2. Clean and normalize
python csv-cleaner.py raw_data.csv --strip --drop-duplicates --fill "N/A"

Enter fullscreen mode Exit fullscreen mode


What's Next

If you found these useful, I've put together a bundle of 10 automation scripts with full documentation, proper error handling, and CLI interfaces for every script. It includes a web scraper, email sender, YouTube transcript downloader, text summarizer, and more — all ready to run.

Check it out here: AI Automation Scripts Bundle

The bundle also comes with a requirements.txt for one-command install and consistent logging across all scripts. Every script has a dry-run mode, so you can preview changes before making them.


Got a favorite automation script? Drop it in the comments. I'm always looking for new ideas to add to the collection.