Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > How can I pass a substitution pattern on the command line?

Reply
Thread Tools

How can I pass a substitution pattern on the command line?

 
 
P B
Guest
Posts: n/a
 
      05-29-2009
I'd like to create a (Linux) perl command line utility that creates
subdirectories based on a common part of several filenames and then
moves the corresponding files into them. The command would (ideally)
look something like this:

makesubdirs.pl 's/^([a-zA-Z+)_\d{2}\.[a-zA-Z]{3}$/$1/' *

If it was issued in a directory containing, for example, the following
files:

image01.jpg
image02.jpg
movie01.mpg
movie02.mpg

it would create an 'image' subdirectory and a 'movie' subdirectory and
move the files, etc., you get the idea.

So, how can I pass the whole s/// operator to the program, to be used
(presumably) thusly (to continue the example used above):

my $pattern = shift @ARGV;
my $subdirectory =~ $pattern;

.... and so on to create the subdirectories, etc.?

Thank you.
 
Reply With Quote
 
 
 
 
A. Sinan Unur
Guest
Posts: n/a
 
      05-29-2009
P B <(E-Mail Removed)> wrote in news:64q5f6xgib.ln2
@soren625.no-ip.org:

> I'd like to create a (Linux) perl command line utility that creates
> subdirectories based on a common part of several filenames and then
> moves the corresponding files into them. The command would (ideally)
> look something like this:
>
> makesubdirs.pl 's/^([a-zA-Z+)_\d{2}\.[a-zA-Z]{3}$/$1/' *
>
> If it was issued in a directory containing, for example, the following
> files:
>
> image01.jpg
> image02.jpg
> movie01.mpg
> movie02.mpg
>
> it would create an 'image' subdirectory and a 'movie' subdirectory and
> move the files, etc., you get the idea.
>
> So, how can I pass the whole s/// operator to the program, to be used
> (presumably) thusly (to continue the example used above):


First, you don't need substitution. You need to capture matches.

Second, just pass the pattern string to the program.

[sinan@kas ~]$ cat s.pl
#!/usr/bin/perl

use strict;
use warnings;

my $pattern = shift @ARGV;
my $re = qr/$pattern/;

for my $arg ( @ARGV ) {
if ( my @parts = ( $arg =~ $re ) ) {
my $subdir = join q{}, @parts;
# put actual code to mkdir, move etc
print "$arg goes in $subdir\n";
}
}

__END__

[sinan@kas ~]$ perl s.pl '\.(\w{1,3})$' *
wallpaper.png goes in png
test.zip goes in zip
etc.zip goes in zip
s.pl goes in pl
t.pl goes in pl
www.zip goes in zip


--
A. Sinan Unur <(E-Mail Removed)>
(remove .invalid and reverse each component for email address)

comp.lang.perl.misc guidelines on the WWW:
http://www.rehabitation.com/clpmisc/
 
Reply With Quote
 
 
 
 
P B
Guest
Posts: n/a
 
      05-30-2009
On 2009-05-29, A. Sinan Unur <(E-Mail Removed)> wrote in
comp.lang.perl.misc:
> First, you don't need substitution. You need to capture matches.
> Second, just pass the pattern string to the program.


> [sinan@kas ~]$ cat s.pl
> #!/usr/bin/perl


> use strict;
> use warnings;


> my $pattern = shift @ARGV;
> my $re = qr/$pattern/;


> for my $arg ( @ARGV ) {
> if ( my @parts = ( $arg =~ $re ) ) {
> my $subdir = join q{}, @parts;
> # put actual code to mkdir, move etc
> print "$arg goes in $subdir\n";
> }
> }


> __END__


> [sinan@kas ~]$ perl s.pl '\.(\w{1,3})$' *
> wallpaper.png goes in png
> test.zip goes in zip
> etc.zip goes in zip
> s.pl goes in pl
> t.pl goes in pl
> www.zip goes in zip


Very Nice. Thank you. I have something similar (though much, much
cruder, and probably much slower) working now, but I'll put your
suggestions to good use.

Now if you don't mind, for my edification, two questions:

What is the 'if' statement testing? What is
( @parts = ( $arg =~ $re ) )
doing? What values is @parts being populated with?

What exactly is the q{} operator doing in the join statement? What is
its content, so to speak? Is it just the same as '' here?

Thanks again for your advice. I'm slowly picking up 'idiomatic perl', so
I'm always eager to learn new things.


On a side note, how /would/ one pass a whole s/// operator on the
command line (sed-style, I guess), supposing you wanted to do
interesting things with backreferences, the g and i modifiers, etc.?
 
Reply With Quote
 
John W. Krahn
Guest
Posts: n/a
 
      05-30-2009
P B wrote:
> On 2009-05-29, A. Sinan Unur <(E-Mail Removed)> wrote in
> comp.lang.perl.misc:
>> First, you don't need substitution. You need to capture matches.
>> Second, just pass the pattern string to the program.

>
>> [sinan@kas ~]$ cat s.pl
>> #!/usr/bin/perl

>
>> use strict;
>> use warnings;

>
>> my $pattern = shift @ARGV;
>> my $re = qr/$pattern/;

>
>> for my $arg ( @ARGV ) {
>> if ( my @parts = ( $arg =~ $re ) ) {
>> my $subdir = join q{}, @parts;
>> # put actual code to mkdir, move etc
>> print "$arg goes in $subdir\n";
>> }
>> }

>
>> __END__

>
>> [sinan@kas ~]$ perl s.pl '\.(\w{1,3})$' *
>> wallpaper.png goes in png
>> test.zip goes in zip
>> etc.zip goes in zip
>> s.pl goes in pl
>> t.pl goes in pl
>> www.zip goes in zip

>
> Very Nice. Thank you. I have something similar (though much, much
> cruder, and probably much slower) working now, but I'll put your
> suggestions to good use.
>
> Now if you don't mind, for my edification, two questions:
>
> What is the 'if' statement testing? What is
> ( @parts = ( $arg =~ $re ) )
> doing? What values is @parts being populated with?


$re is the regular expression '\.(\w{1,3})$'. $arg is a file name. $re
is matched against $arg and everything inside capturing parentheses is
returned and stored in @parts. If @parts is empty then it is false and
the next file name is processed.

> What exactly is the q{} operator doing in the join statement? What is
> its content, so to speak? Is it just the same as '' here?


q{} is exactly the same as ''.

> Thanks again for your advice. I'm slowly picking up 'idiomatic perl', so
> I'm always eager to learn new things.
>
>
> On a side note, how /would/ one pass a whole s/// operator on the
> command line (sed-style, I guess), supposing you wanted to do
> interesting things with backreferences, the g and i modifiers, etc.?


perldoc -q "How can I expand variables in text strings"



John
--
Those people who think they know everything are a great
annoyance to those of us who do. -- Isaac Asimov
 
Reply With Quote
 
P B
Guest
Posts: n/a
 
      06-01-2009
On 2009-05-30, John W. Krahn <(E-Mail Removed)> wrote in
comp.lang.perl.misc:
> P B wrote:
>> On 2009-05-29, A. Sinan Unur <(E-Mail Removed)> wrote in
>> comp.lang.perl.misc:
>>> First, you don't need substitution. You need to capture matches.
>>> Second, just pass the pattern string to the program.


[snipped A. Sinan Unur's example]

>> What is the 'if' statement testing? What is
>> ( @parts = ( $arg =~ $re ) )
>> doing? What values is @parts being populated with?


> $re is the regular expression '\.(\w{1,3})$'. $arg is a file name. $re
> is matched against $arg and everything inside capturing parentheses is
> returned and stored in @parts. If @parts is empty then it is false and
> the next file name is processed.


>> What exactly is the q{} operator doing in the join statement? What is
>> its content, so to speak? Is it just the same as '' here?


> q{} is exactly the same as ''.


>> Thanks again for your advice. I'm slowly picking up 'idiomatic perl', so
>> I'm always eager to learn new things.
>>
>>
>> On a side note, how /would/ one pass a whole s/// operator on the
>> command line (sed-style, I guess), supposing you wanted to do
>> interesting things with backreferences, the g and i modifiers, etc.?


> perldoc -q "How can I expand variables in text strings"


Many thanks to both A. Sinan Unur and John W. Krahn for your helpful examples
and explanations. I've incorporated them into my script and it's working
much more reliable and fast now.
 
Reply With Quote
 
sln@netherlands.com
Guest
Posts: n/a
 
      06-02-2009
On Mon, 01 Jun 2009 12:47:41 -0400, P B <(E-Mail Removed)> wrote:

>On 2009-05-30, John W. Krahn <(E-Mail Removed)> wrote in
>comp.lang.perl.misc:
>> P B wrote:
>>> On 2009-05-29, A. Sinan Unur <(E-Mail Removed)> wrote in
>>> comp.lang.perl.misc:
>>>> First, you don't need substitution. You need to capture matches.
>>>> Second, just pass the pattern string to the program.

>
>[snipped A. Sinan Unur's example]
>
>>> What is the 'if' statement testing? What is
>>> ( @parts = ( $arg =~ $re ) )
>>> doing? What values is @parts being populated with?

>
>> $re is the regular expression '\.(\w{1,3})$'. $arg is a file name. $re
>> is matched against $arg and everything inside capturing parentheses is
>> returned and stored in @parts. If @parts is empty then it is false and
>> the next file name is processed.

>
>>> What exactly is the q{} operator doing in the join statement? What is
>>> its content, so to speak? Is it just the same as '' here?

>
>> q{} is exactly the same as ''.

>
>>> Thanks again for your advice. I'm slowly picking up 'idiomatic perl', so
>>> I'm always eager to learn new things.
>>>
>>>
>>> On a side note, how /would/ one pass a whole s/// operator on the
>>> command line (sed-style, I guess), supposing you wanted to do
>>> interesting things with backreferences, the g and i modifiers, etc.?

>

^^^^^^^^^^
You can't pass that form via string and expect it to work on the replacement
side (ie: s/pattern/replacement/) without doing an eval on it within the script.

Also, one must be carefull of shell interactions.
Example:
windows - perl hh.pl 'arg1'. $ARGV[0] is '<quote>arg1<quote>'
windows - perl hh.pl arg1. $ARGV[0] is 'arg1'
windows - perl hh.pl "arg1". $ARGV[0] is 'arg1'
windows - perl hh.pl arg1 and more. $ARGV[0] is 'arg1'
windows - perl hh.pl "arg1 and more". $ARGV[0] is 'arg1 and more'
---
use strict;
use warnings;

my $pattern = shift @ARGV;
my $string = q/take MEME out/;

print "\"$string\" =~ $pattern\n";

eval "\$string =~ $pattern";

print $string,"\n";

__END__


c:\temp>perl aa.pl "s/(ME)\1/$1/"

"take MEME out" =~ s/(ME)\1/$1/
take ME out

c:\temp>


-sln
 
Reply With Quote
 
P B
Guest
Posts: n/a
 
      06-03-2009
On 2009-06-02, http://www.velocityreviews.com/forums/(E-Mail Removed) <(E-Mail Removed)> wrote in
comp.lang.perl.misc:
>>> P B wrote:


>>>> On a side note, how /would/ one pass a whole s/// operator on the
>>>> command line (sed-style, I guess), supposing you wanted to do
>>>> interesting things with backreferences, the g and i modifiers,
>>>> etc.?


> ^^^^^^^^^^ You can't pass that form via string and expect it
> to work on the replacement side (ie: s/pattern/replacement/)
> without doing an eval on it within the script.


Thanks for the bit about the eval. That fills in the blanks on how to
make the s/// argument work with backreferences.

> Also, one must be carefull of shell interactions.
> Example:
> windows - perl hh.pl 'arg1'. $ARGV[0] is '<quote>arg1<quote>'
> windows - perl hh.pl arg1. $ARGV[0] is 'arg1'
> windows - perl hh.pl "arg1". $ARGV[0] is 'arg1'
> windows - perl hh.pl arg1 and more. $ARGV[0] is 'arg1'
> windows - perl hh.pl "arg1 and more". $ARGV[0] is 'arg1 and more'


Noted. I do work with ActivePerl in Windows occasionally, but I intend
to use this method exclusively in a Unix-like environment.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: How include a large array? Edward A. Falk C Programming 1 04-04-2013 08:07 PM
gsub pattern substitution and ${...} Sarah Allen Ruby 7 05-11-2009 01:00 PM
Pattern based substitution Daniel Mircea Ruby 0 10-16-2006 05:17 PM
Regular Expression for pattern substitution Vibha Tripathi Python 3 07-01-2005 06:31 PM
speed issues with pattern matching and substitution Arturi Perl Misc 8 04-05-2005 10:19 AM



Advertisments