A high-performance shell script tool to organize photos based on EXIF metadata, with automatic parallel processing for efficient handling of large photo collections.
- Organize photos by date, camera, or both
- Copy or move files to organized structure
- Preserve original metadata
- Handle duplicate files safely
- Extract EXIF data for organization
- Support for dry-run mode to preview changes
- Recursive directory processing option
- Detailed logging with verbose mode
- Parallel processing for improved performance
- Auto-detection of available CPU cores
- Linux/Unix environment
- Bash shell
- ExifTool (for metadata extraction)
- Standard Linux utilities
-
Clone this repository:
git clone https://github.com/yourusername/photo-organizer.git -
Make the script executable:
chmod +x photo_organizer.sh -
Install ExifTool (if not already installed):
- On Ubuntu/Debian:
sudo apt-get install libimage-exiftool-perl - On Fedora:
sudo dnf install perl-Image-ExifTool - On macOS with Homebrew:
brew install exiftool - More installation options: https://exiftool.org/install.html
- On Ubuntu/Debian:
./photo_organizer.sh [OPTIONS] SOURCE_DIRECTORY
-o, --output DIR: Output directory (default: organized_photos)-b, --organize-by TYPE: Organize by: date, camera, both (default: date)-m, --move: Move files instead of copying-d, --dry-run: Show what would be done without making changes-r, --recursive: Process directories recursively-v, --verbose: Enable verbose output-p, --parallel: Enable parallel processing (default)-s, --sequential: Disable parallel processing and use sequential processing-j, --jobs NUM: Number of parallel jobs (default: auto-detected based on CPU cores)-h, --help: Display help message--version: Display version information
# Organize photos by date with automatic parallel processing (default)
./photo_organizer.sh ~/Pictures
# Organize by camera model
./photo_organizer.sh -o ~/Sorted -b camera ~/Pictures
# Move files instead of copying, with recursive directory processing
./photo_organizer.sh -m -r ~/Pictures
# Use sequential processing (disable parallel processing)
./photo_organizer.sh -s ~/Pictures
# Specify number of parallel jobs
./photo_organizer.sh -j 8 ~/Pictures
# Preview changes without modifying files
./photo_organizer.sh -d -v ~/Pictures
organized_photos/
├── 2023/
│ ├── 01/
│ │ ├── IMG_0001.jpg
│ │ └── IMG_0002.jpg
│ └── 02/
│ ├── IMG_0003.jpg
│ └── ...
└── 2022/
└── ...
organized_photos/
├── Canon_EOS_R5/
│ ├── IMG_0001.jpg
│ └── IMG_0002.jpg
├── iPhone_13_Pro/
│ └── IMG_0003.jpg
└── Nikon_Z6/
└── ...
organized_photos/
├── Canon_EOS_R5/
│ ├── 2023/
│ │ ├── 01/
│ │ │ └── IMG_0001.jpg
│ │ └── ...
│ └── 2022/
│ └── ...
├── iPhone_13_Pro/
│ └── ...
└── Nikon_Z6/
└── ...
- Run script:
bash photo_organizer.sh - Lint shell scripts:
shellcheck photo_organizer.sh - Test EXIF extraction:
exiftool -a -u -g1 test_image.jpg
The project includes a comprehensive test suite to verify functionality with various EXIF data scenarios:
- Create test images:
cd test_images && ./create_test_images.sh - Setup test cases:
cd test_scripts && ./setup_test_images.sh - Run all tests:
cd test_scripts && ./run_all_tests.sh - Run single test:
bash test_scripts/test_single.sh TEST_NAME
Test scenarios include:
- Complete EXIF data (with dates and camera information)
- Partial EXIF data (missing DateTimeOriginal but having CreateDate)
- No EXIF data (using file timestamps)
- Various organization methods (by date, camera, or both)
This project uses GitHub Actions for continuous integration:
- Automatically runs all tests on push and pull requests
- Performs shellcheck analysis on all shell scripts
- Verifies the script works with different EXIF scenarios
MIT License
Contributions are welcome! Please feel free to submit a Pull Request.