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

Discussion in 'Perl Misc' started by P B, May 29, 2009.

  1. P B

    P B Guest

    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.
     
    P B, May 29, 2009
    #1
    1. Advertising

  2. P B <> 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 <>
    (remove .invalid and reverse each component for email address)

    comp.lang.perl.misc guidelines on the WWW:
    http://www.rehabitation.com/clpmisc/
     
    A. Sinan Unur, May 29, 2009
    #2
    1. Advertising

  3. P B

    P B Guest

    On 2009-05-29, A. Sinan Unur <> 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.?
     
    P B, May 30, 2009
    #3
  4. P B wrote:
    > On 2009-05-29, A. Sinan Unur <> 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
     
    John W. Krahn, May 30, 2009
    #4
  5. P B

    P B Guest

    On 2009-05-30, John W. Krahn <> wrote in
    comp.lang.perl.misc:
    > P B wrote:
    >> On 2009-05-29, A. Sinan Unur <> 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.
     
    P B, Jun 1, 2009
    #5
  6. P B

    Guest

    On Mon, 01 Jun 2009 12:47:41 -0400, P B <> wrote:

    >On 2009-05-30, John W. Krahn <> wrote in
    >comp.lang.perl.misc:
    >> P B wrote:
    >>> On 2009-05-29, A. Sinan Unur <> 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
     
    , Jun 2, 2009
    #6
  7. P B

    P B Guest

    On 2009-06-02, <> 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.
     
    P B, Jun 3, 2009
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. BartlebyScrivener

    can't pass command-line arguments

    BartlebyScrivener, Apr 10, 2006, in forum: Python
    Replies:
    13
    Views:
    628
    Duncan Booth
    Apr 11, 2006
  2. Tim Golden

    RE: can't pass command-line arguments

    Tim Golden, Apr 10, 2006, in forum: Python
    Replies:
    11
    Views:
    774
    BartlebyScrivener
    Apr 13, 2006
  3. Trent Mick

    Re: can't pass command-line arguments

    Trent Mick, Apr 11, 2006, in forum: Python
    Replies:
    0
    Views:
    396
    Trent Mick
    Apr 11, 2006
  4. kmietas
    Replies:
    6
    Views:
    522
    Default User
    Apr 19, 2006
  5. Geezer From The Freezer

    substitution from command line

    Geezer From The Freezer, Apr 23, 2004, in forum: Perl Misc
    Replies:
    3
    Views:
    92
    Tad McClellan
    Apr 24, 2004
Loading...

Share This Page