#!/usr/bin/perl # Date : 4-20-2000 # Author : James Dean Palmer # # Description : # # This script performs file renaming / renumbering / copying tasks based # on a silly grammar that I made up. Type "renumber --help" for more # information. use Getopt::Long; sub in_and_out { if (!(defined $in)) { $in = $_[0]; } elsif (!(defined $out)) { $out = $_[0]; } else { $opt_help = 1; } }; &GetOptions("debug", "preview", "copy", "help", "<>", \&in_and_out); if ((!defined $in) || (!defined $out)) { $opt_help = 1; } if ($opt_help) { print "Usage: renumber [OPTION] \"SOURCE\" \"DEST\"\n"; print "Rename SOURCE to DEST using renumber rules.\n\n"; print " --help This message\n"; print " --copy Copy the file instead of moving it\n"; print " --preview Preview what is about to happen\n"; print "\n"; print "Renumber rules:\n\n"; print " (\#)\n"; print " (\#,N)\n"; print " (\#,N,START)\n"; print " (\#,N,START,END)\n"; print "\n"; print "Any of the above forms is valid where,\n"; print "\n"; print " N = The number of digits to match when used in SOURCE. If this \n"; print " is set to 0, any number of digits is matched. N is the\n"; print " number of digits to print in DEST. If the number to be \n"; print " printed in DEST is longer than N, it will be longer than N.\n"; print "\n"; print " START = The number to start the match at in SOURCE. START is the\n"; print " number to start renumbering at in DEST.\n"; print "\n"; print " END = The number to end the match at in SOURCE. END is the number\n"; print " to stop at in DEST.\n"; print "\n"; print "Caveats:\n\n"; print " Re-numbering takes place based on the sorted file order when using\n"; print " START and/or END.\n\n"; print " Wild cards may be used in both SOURCE and DEST.\n\n"; print " SOURCE and DEST must be quoted, otherwise your shell tries to \n"; print " interpret the wild cards and parans.\n\n"; print "Examples:\n\n"; print " Renumber frames.##.tga to frames.#####.tga:\n"; print " renumber \"frames.(\#,2).tga\" \"frames.(\#,5).tga\"\n\n"; print " Renumber frames.???.tga to frames.#####.tga, where ??? is an\n"; print " unknown number of digits:\n"; print " renumber \"frames.(\#).tga\" \"frames.(\#,5).tga\"\n\n"; print " Use wild cards in the name:\n"; print " renumber \"*.(\#).tga\" \"*.(\#,5).tga\"\n\n"; print " Use multiple wild cards in the name:\n"; print " renumber \"*.(\#).*\" \"*.(\#,5).*\"\n\n"; print " Renumber frames 22-46 to 0093+:\n"; print " renumber \"frames.(\#,0,22,46).tga\" \"frames.(\#,4,93).tga\"\n\n"; print "Report bugs to James Dean Palmer \n"; exit (0); } # $in The input file expression. $in_path = ""; # The input file path. # $out The output file expression. $out_path = ""; # The output file path. # $wild_in The input file expression with wild cards. $digits = ""; # The expression to match digits. $renumber = 0; # Should renumbering be done? $renumber_start = 0; # start point for renumbering. $renumber_end = 1000000000; # end point for renumbering. # First lets list all the files in IN, and see what matches. while ($in =~ m/\//) { $in =~ s/(.*\/)//; $in_path .= $1; } while ($out =~ m/\//) { $out =~ s/(.*\/)//; $out_path .= $1; } if (!($in_path)) { $dir = "."; } else { $dir = $in_path; } if (!(opendir INDIR, "$dir")) { print STDERR "Could not open input directory, \"$dir\".\n"; exit (0); } # Skip . and .. readdir INDIR; readdir INDIR; # Get the sorted directory list. @files = readdir INDIR; closedir INDIR; @files = sort @files; # Escape out escapes. $in =~ s/\\/\\\\/g; $wild_in = $in; # Build a regular expression based on $in. if ($in =~ m/\(\#\s*\)/) { $digits = "\\d+"; } elsif ($in =~ m/\(\#\s*\,\s*(\d+)\s*\)/) { my ($cnt) = $1; for ($i=0; $i<$cnt; $i++) { $digits .= "\\d"; } if ($cnt == 0) { $digits = "\\d+"; } } elsif ($in =~ m/\(\#\s*\,\s*(\d+)\s*,\s*(\d+)\s*\)/) { my ($cnt) = $1; $start_match = $2; for ($i=0; $i<$cnt; $i++) { $digits .= "\\d"; } if ($cnt == 0) { $digits = "\\d+"; } } elsif ($in =~ m/\(\#\s*\,\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/) { my ($cnt) = $1; $start_match = $2; $end_match = $3; for ($i=0; $i<$cnt; $i++) { $digits .= "\\d"; } if ($cnt == 0) { $digits = "\\d+"; } } # Match a renumber rule: $in =~ s/\(\#[ \,\d]*\)/\($digits\)/; $wild_in =~ s/\(\#[ \,\d]*\)/$digits/; # Match wild cards: $in =~ s/\*/\\D\*/g; $wild_cnt = ($wild_in =~ s/\*/\(\\D\*\)/g); # Build a format based on $out. if ($out =~ s/\(\#\s*\,\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)/__replace__/) { $digit_cnt = $1; $renumber_start = $2; $renumber_end = $3; $renumber = 1; } elsif ($out =~ s/\(\#\s*\,\s*(\d+)\s*,\s*(\d+)\s*\)/__replace__/) { $digit_cnt = $1; $renumber_start = $2; $renumber = 1; } elsif ($out =~ s/\(\#\s*\,\s*(\d+)\s*\)/__replace__/) { $digit_cnt = $1; } elsif ($out =~ s/\(\#\s*\)/__replace__/) { $digit_cnt = 0; } if ($opt_debug) { print "in =\"$in\"\n"; print "out =\"$out\"\n"; print "wild_in =\"$wild_in\"\n"; print "in_path =\"$in_path\"\n"; print "out_path =\"$out_path\"\n"; } $renumber_next = $renumber_start; foreach $file (@files) { if ($file =~ m/$in/) { my ($number) = ""; $number = $1; if ((!defined $start_match) || (int ($number) >= int ($start_match))) { if ((!defined $end_match) || (int ($number) <= int ($end_match))) { if ($renumber_next > $renumber_end) { print STDERR "Reached end count ($renumber_end).\n"; exit (0); } if ($renumber) { $number = $renumber_next; } $renumber_next++; if ($digits) { $number = sprintf ("%0." . $digit_cnt . "d", int ($number)); } $newfile = $out; $newfile =~ s/__replace__/$number/; for ($i=0; $i<$wild_cnt; $i++) { my ($r); $file =~ m/$wild_in/; $r = ${$i+1}; $newfile =~ s/\*/$r/; } $xxx = "$in_path$file $out_path$newfile"; if ($opt_preview) { if ($opt_copy) { print "cp $xxx\n"; } else { print "mv $xxx\n"; } } else { if ($opt_copy) { print "cp $xxx\n"; print `cp $xxx`; } else { print "mv $xxx\n"; print `mv $xxx`; } } } } } }