Skip to content

Setup — File Organizer

Create the project directory and a test sandbox before writing any code.

Directory Structure

mkdir -p ~/projects/file-organizer
cd ~/projects/file-organizer
touch file_organizer.sh
chmod +x file_organizer.sh

Your project directory:

~/projects/file-organizer/ ├── file_organizer.sh ← script you will write └── organizer.log ← created on first run

Create a Test Sandbox

Before touching any real directory, build a sandbox full of mixed files to test against:

mkdir -p ~/projects/file-organizer/test_sandbox
cd ~/projects/file-organizer/test_sandbox

# Images
touch photo.jpg screenshot.png banner.svg

# Documents
touch report.pdf notes.txt readme.md spreadsheet.csv

# Videos
touch lecture.mp4 tutorial.mkv

# Audio
touch podcast.mp3 ambient.flac

# Archives
touch backup.tar.gz source.zip

# Code
touch deploy.sh analysis.py index.js

# Edge cases
touch "file with spaces.txt"
touch .dotfile
touch no_extension
touch duplicate.jpg   # we will copy this to test dedup

mkdir subdir_to_skip   # should be ignored

Verify the sandbox:

ls -la ~/projects/file-organizer/test_sandbox/
total 0 drwxr-xr-x 2 user user 480 Jan 15 09:00 . drwxr-xr-x 3 user user 96 Jan 15 09:00 .. -rw-r--r-- 1 user user 0 Jan 15 09:00 .dotfile -rw-r--r-- 1 user user 0 Jan 15 09:00 ambient.flac -rw-r--r-- 1 user user 0 Jan 15 09:00 analysis.py -rw-r--r-- 1 user user 0 Jan 15 09:00 backup.tar.gz ...

Verify Prerequisite Commands

Run each command to confirm it works on your system:

# Move a file (dry run with echo)
echo mv source.txt dest.txt
mv source.txt dest.txt

# Extract extension from a filename
filename="photo.jpg"
echo "${filename##*.}"
jpg

# Lowercase a string (bash 4+)
ext="JPG"
echo "${ext,,}"
jpg

# Check if a path is a regular file (not a directory)
test -f /etc/hostname && echo "is a file"
is a file

# Create directory tree silently
mkdir -p /tmp/organizer_test/Images
echo $?
0

Bash 4+ required

${var,,} (lowercase) requires bash 4.0+. macOS ships with bash 3.2. Either install bash 4+ via Homebrew or use tr '[:upper:]' '[:lower:]' as a portable fallback.

Confirm No Conflicts

# Ensure no existing file_organizer.sh in PATH would shadow yours
which file_organizer.sh 2>/dev/null || echo "not in PATH — good"
not in PATH — good


requirements | implementation