#!/usr/bin/perl -w # # Organize a folder full of picture files into subfolders by name. # # To do: # load all _* dir names, and nab all files that contain a dir name. # on those dir names, try inverting around _, and dropping _, too. use strict; if ($ARGV[0] eq "-h") { warn "Moves files into sub-folders based on common parts of their names, ignoring\n"; warn " any final digits.\n"; warn "Also normalizes extensions jpg/jpeg/JPG/JPEG, renames to lose odd characters.\n"; exit; } print "Number of files: " . `ls | wc -l` . "\n"; # Normalize file extensions # my $ls = `ls`; my @files = split('\n',$ls); foreach my $x (@files) { my $newName = $x; $newName =~ s/\.JPG/.jpg/; $newName =~ s/\.JPEG/.jpg/; $newName =~ s/\.jpeg/.jpg/; if ($x ne $newName) { print "moving '$x' to '$newName'\n"; rename($x,$newName); } } # Clean up the character set # $ls = `ls \*.jpg`; @files = split('\n',$ls); foreach $x (@files) { $newName = $x; # $newName =~ s/[- ~!@#\$%^&*()=+{}|;:<>,?\\\/\'\"]/_/g; $newName =~ s/[^a-zA-Z0-9_.]/_/g; $newName =~ s/__+/_/g; if ($x ne $newName) { print "normalizing filename '$x' to '$newName'\n"; rename($x,$newName); } } # Strip extensions and serial numbers to find common base names. # But if there's A1.jpg and Amarillo1.jpg, don't put all under A. # my $prefixes = `ls [a-zA-Z]*[0-9]*.jpg [0-9]*[a-zA-Z_]*[0-9]*.jpg | sed 's/index//' | sed 's/[0-9]*\.jpg//' | sort | uniq`; my @plist = split('\n', $prefixes); foreach $x (@plist) { next unless ($x ne ""); my @group = glob("$x*"); my $nfiles = scalar(@group); if ($nfiles > 1) { # print "Globbed $x and got $nfiles items.\n"; my $i = 0; while ($i < scalar(@group)) { if (@group[$i] !~ m/$x[0-9]+\.jpg/ || -d @group[$i]) { delete @group[$i]; } $i++; } $nfiles = scalar(@group); if ($nfiles <= 1) { #print " but none have just numbers after '$x'\n"; } else { $totaldirs++; print "Moving $nfiles files for '$x*' to '_$x/'\n"; if (-e "_$x" == 0) { mkdir("_$x"); } foreach $f (@group) { rename($f, "_$x/$f"); $total++; } } } } print "Moving all-numeric files to _numeric/...\n"; system "mkdir -p _numeric"; my @ns = `ls [0-9]*[0-9].jpg`; $totaldirs++; for $f (@ns) { chomp $f; if ($f =~ m/^\d+\.jpg$/) { rename($f, "_numeric/$f"); $total++; } } print "Done, $total files grouped into $totaldirs directories.\n"; my $left = `ls -F | grep -v '/' | wc -l` - 0; print " ($left files left ungrouped)\n"; exit;