Files

173 lines
5.2 KiB
Bash

#!/bin/bash
# Parse arguments
DRY_RUN=false
INPUT_DIR=""
OUTPUT_DIR=""
while [[ $# -gt 0 ]]; do
case $1 in
--dry-run|-n)
DRY_RUN=true
shift
;;
--input|-i)
INPUT_DIR="$2"
shift 2
;;
--output|-o)
OUTPUT_DIR="$2"
shift 2
;;
--help|-h)
echo "Usage: $0 --input DIR --output DIR [OPTIONS]"
echo ""
echo "Required:"
echo " --input, -i DIR Input directory containing videos"
echo " --output, -o DIR Output directory for organized videos"
echo ""
echo "Options:"
echo " --dry-run, -n Preview changes without moving files"
echo " --help, -h Show this help message"
exit 0
;;
*)
echo "Unknown option: $1"
echo "Use --help for usage information"
exit 1
;;
esac
done
# Validate required arguments
if [[ -z "$INPUT_DIR" ]]; then
echo "Error: --input directory is required"
echo "Use --help for usage information"
exit 1
fi
if [[ -z "$OUTPUT_DIR" ]]; then
echo "Error: --output directory is required"
echo "Use --help for usage information"
exit 1
fi
# Check if input directory exists
if [[ ! -d "$INPUT_DIR" ]]; then
echo "Error: Input directory '$INPUT_DIR' does not exist"
exit 1
fi
# Check if exiftool is installed
if ! command -v exiftool &> /dev/null; then
echo "Error: exiftool is not installed. Please install it first."
echo " Ubuntu/Debian: sudo apt-get install libimage-exiftool-perl"
echo " macOS: brew install exiftool"
exit 1
fi
# Create output directory (only if not dry-run)
if [[ "$DRY_RUN" == false ]]; then
mkdir -p "$OUTPUT_DIR"
fi
# Counters
processed=0
skipped=0
failed=0
if [[ "$DRY_RUN" == true ]]; then
echo "🔍 DRY RUN MODE - No files will be moved"
fi
echo "Starting video organization..."
echo "Input directory: $INPUT_DIR"
echo "Output directory: $OUTPUT_DIR"
echo ""
# Process each video
# Using -iname for case-insensitive matching (matches .mp4, .MP4, .Mp4, etc.)
while IFS= read -r video; do
echo "Processing: $(basename "$video")"
# Extract creation date (YYYYMMDD)
creation_date=$(exiftool -MediaCreateDate -d "%Y%m%d" -s3 "$video" 2>/dev/null | head -n 1 | tr -d ' ')
# Check if date was extracted successfully
if [[ -z "$creation_date" ]] || [[ ! "$creation_date" =~ ^[0-9]{8}$ ]]; then
echo " ⚠ Warning: Could not extract valid date, moving to Unknown folder"
target_dir="$OUTPUT_DIR/Unknown"
destination="$target_dir/$(basename "$video")"
# Check if destination file already exists
if [[ -f "$destination" ]]; then
# Add timestamp to avoid overwrite
filename=$(basename "$video")
extension="${filename##*.}"
basename_no_ext="${filename%.*}"
destination="$target_dir/${basename_no_ext}_$(date +%s).$extension"
echo " ⚠ File exists, renaming to: $(basename "$destination")"
fi
if [[ "$DRY_RUN" == true ]]; then
echo " → Would move to: Unknown/$(basename "$destination")"
else
mkdir -p "$target_dir"
if mv "$video" "$destination" 2>/dev/null; then
echo " ✓ Moved to: Unknown/"
else
echo " ✗ Failed to move file"
failed=$((failed + 1))
continue
fi
fi
skipped=$((skipped + 1))
continue
fi
# Extract year, month, day
year="${creation_date:0:4}"
month="${creation_date:4:2}"
day="${creation_date:6:2}"
# Create subdirectories (YYYY/MM/DD)
target_dir="$OUTPUT_DIR/$year/$month/$day"
# Check if destination file already exists
destination="$target_dir/$(basename "$video")"
if [[ -f "$destination" ]]; then
# Add timestamp to avoid overwrite
filename=$(basename "$video")
extension="${filename##*.}"
basename_no_ext="${filename%.*}"
destination="$target_dir/${basename_no_ext}_$(date +%s).$extension"
echo " ⚠ File exists, renaming to: $(basename "$destination")"
fi
if [[ "$DRY_RUN" == true ]]; then
# Dry run: just show what would happen
echo " → Would move to: $year/$month/$day/$(basename "$destination")"
processed=$((processed + 1))
else
# Actually perform the move
mkdir -p "$target_dir"
if mv "$video" "$destination" 2>/dev/null; then
echo " ✓ Moved to: $year/$month/$day/"
processed=$((processed + 1))
else
echo " ✗ Failed to move file"
failed=$((failed + 1))
fi
fi
done < <(find "$INPUT_DIR" -type f \( -iname "*.mp4" -o -iname "*.mov" -o -iname "*.mkv" -o -iname "*.avi" -o -iname "*.wmv" -o -iname "*.flv" -o -iname "*.webm" \))
echo ""
if [[ "$DRY_RUN" == true ]]; then
echo "DRY RUN Summary:"
echo " Would process: $processed"
echo " Would move to Unknown: $skipped"
else
echo "Summary:"
echo " Processed: $processed"
echo " Moved to Unknown: $skipped"
echo " Failed: $failed"
fi