Re: rename 0.3 - now with two extra cupholders
rename -z, gives me a Use of uninitialized value in concatenation (.) or string at (eval 3) line 1 error, which I tracked down to an unescaped $:-
178c178
< 'z|sanitize' => sub { push @perlexpr, 's/[!"$&()=?`*\'
+;<>|_[:cntrl:][:blank:]]+/_/g' },
---
> 'z|sanitize' => sub { push @perlexpr, 's/[!"\$&()=?`*\
+';<>|_[:cntrl:][:blank:]]+/_/g' },
I am intrigued why you opted for s/// vs. tr/// though? Surely tr/// is more appropriate for both this and the case options?
'c|lower-case' => sub { push @perlexpr, 'tr/A-Z/a-z/' },
'C|upper-case' => sub { push @perlexpr, 'tr/a-z/A-Z/' },
'z|sanitize' => sub { push @perlexpr, 'tr/A-Za-z0-9\.\-/_/cs' },
That's a little more extreme sanitization than you were doing, but that's easy to fix by adding other allowed characters, and this way you'd also get pre-5.6 compatability. :-)
And if you're looking for potential feature ads, I ported over some concepts from my own spin on Larry's rename script.
18a19,20
> S<B<[ -g ]>>
> S<B<[ -I ]>>
21a24,25
> S<B<[ -p plugin ]>>
> S<B<[ -r ]>>
99a104,111
> =item B<-g>, B<--glob>
>
> Use Perl's builtin C<glob> function to pre-parse @ARGV. Useful for s
+hells that don't provide their own shell globbing. (eg, cmd.exe)
>
> =item B<-I>, B<--include-directory>
>
> Prepend directory to search path ("@INC") for plugins (see C<-p>) an
+d other modules.
>
115a128,135
> =item B<-p>, B<--plugin>
>
> ...
>
> =item B<-r>, B<--reverse-file-order>
>
> Process filenames in reverse (last to first) order.
>
155a176,184
> my %plugin_hooks = ( 'pre' => [ ], 'post' => [ ] );
>
> sub run_hooks {
> my($type) = @_;
>
> for my $hook ( @{ $plugin_hooks{$type} } ) {
> $hook->();
> }
> }
164a194,195
> 'g|glob' => \my $opt_glob,
> 'I|include-path=s' => sub { unshift @INC, $_[1] },
168a200,216
> 'p|plugin|macro=s' => sub {
> return if $_[1] !~ /\A(\w+(::\w+)*)\z/;
>
> require File::Spec;
>
> my $plugin_name = "Rename::$1";
> my $plugin_file = File::Spec->catfile( split /::/, $
+plugin_name ) . '.pm';
>
> require $plugin_file;
>
> for my $type ( keys %plugin_hooks ) {
> if ( my $coderef = $plugin_name->can( $type . "_hook" )
+) {
> push @{ $plugin_hooks{$type} }, $coderef;
> }
> }
> },
> 'r|reverse-file-order' => \my $opt_reverse_order,
178c226
< 'z|sanitize' => sub { push @perlexpr, 's/[!"$&()=?`*\'
+;<>|_[:cntrl:][:blank:]]+/_/g' },
---
> 'z|sanitize' => sub { push @perlexpr, 's/[!"\$&()=?`*\
+';<>|_[:cntrl:][:blank:]]+/_/g' },
184c232
< if(@ARGV) { push @perlexpr, shift }
---
> if(@ARGV and ! -e $ARGV[0]) { push @perlexpr, shift }
212a261,263
> if ($opt_glob) { @ARGV = map glob($_), @ARGV; }
> if ($opt_reverse_order) { @ARGV = reverse @ARGV; }
>
220a272
> run_hooks('pre');
221a274
> run_hooks('post');
Didn't finish off all the accompanying POD, yet, but hopefully you can see the benefits in some of this, although some examples might help...
rename -r -g "s/(\d+)/$1+1/e" *.txt
vs. rename "s/(\d+)/$1+1/e" 99.txt 98.txt 97.txt .. 1.txt
And to borrow from your -mp3 idea...
package Rename::MP3;
require MP3::Info;
sub pre_hook {
my $mp3 = MP3::Info::get_mp3tag($_);
while ( my($field,$value) = each %$mp3 ) {
${"main::$field"} = $value;
}
}
...and then...
rename -p MP3 'no strict "vars"; $_ = "$ARTIST - $ALBUM ($YEAR)- $TRACKNUM - $TITLE.mp3"' *.mp3
(NB. I haven't rigourously tested all this code so don't experiment on things you can't afford to lose!)
Two-dimensional array to "Excel" format
Re: The Future - Managing Modules
Chatterbox2IRC bridge using POE and XML::Simple
Categorized Questions and Answers
Message Inbox
|