Bulk File Renamer and Organizer Script
Write a Perl script that tidies up a messy folder, such as a Downloads folder. It cleans up file names using regular expressions (spaces to underscores, lowercase, removing strange characters) and sorts the files into subfolders by type (images/, documents/, music/…) or by date (2024/07/). It shows you the plan first, changes nothing until you confirm, and never overwrites an existing file. Every change is written to a log file so you can see or undo what happened. You'll practice Perl regular expressions, walking directories with File::Find, and safe file operations using only modules that come with Perl.
- Estimate
- ~8.5h
- Steps
- 6
- Completed by
- 0
- Proposed by
- codeseed.app
File::Find · Perl core modules
Project roadmap
- 01
Set up the script
~1hCreate organize.pl with use strict and use warnings. Use Getopt::Long to read: the target directory (required), --by type or --by date (default type) and --apply (really make changes; without it the script only shows the plan). Print a usage message and exit if the directory doesn't exist. Done when: running with --help or an invalid directory prints a clear message.
- 02
Collect the files
~1hUse File::Find to collect every regular file in the directory and its subfolders, skipping hidden files (names starting with a dot) and the log file itself. Store each file's full path in an array. Done when: the script prints the list of files it found in a test folder.
- 03
Clean up file names with regex
~2hWrite clean_name($name) that keeps the extension and, for the rest of the name: lowercases it, replaces spaces and dashes with underscores, removes characters other than letters, numbers, underscores and dots, collapses repeated underscores, and trims underscores at the ends. For example My Photo (1).JPG becomes my_photo_1.jpg. Done when: clean_name gives the right result for at least 6 example names.
- 04
Decide the target folder
~1.5hWith --by type, map extensions to folders using a hash: images (jpg, png, gif), documents (pdf, docx, txt), music (mp3, wav), archives (zip, tar, gz), and other for everything else. With --by date, use the file's modification time from stat and localtime to build a folder like 2024/07. Done when: every file gets a correct target path in the plan.
- 05
Show the plan and avoid collisions
~1.5hPrint the plan as old path -> new path. If a target already exists, or two files would get the same new name, add _1, _2 and so on. Skip files that are already in the right place with the right name. Without --apply, stop here. Done when: the dry run shows every planned move, and nothing on disk changes.
- 06
Apply the changes and log them
~1.5hWith --apply, create missing folders with File::Path's make_path, move files with File::Copy's move, and append each change to organize.log as a tab-separated line with the time, old path and new path. Report any file that couldn't be moved and continue with the others. Print a summary at the end. Done when: the files are organized and every move is listed in organize.log.
Ready to build this?
Get a GitHub repo and start building. Your AI reviewer checks each step as you go.
Tech stack