Hagbone has asked for the wisdom of the Perl Monks concerning the following question:

Oh wise ones ......

I'm relatively comfortable using perl's regex language, but have a feeling that command line items speak a different form of the regex-speak.

If I were using a direct perl regex, something like:

if ($whatever =~ m~$logs/access_log\.\d+\.gz~) {#something}
works. But a line like:

open(TAR,"tar -czpf $target_file $logs/access_log\.d+\.gz |");
Doesn't, and offers:

tar: /wwwusr/www1/woodweb/logs/access_log.d+.gz: Cannot stat: No such +file or directory
I'm hoping someone can point me towards a resource that will explain the nuances of using regex's within command line type syntax ....

Replies are listed 'Best First'.
Re: Acceptable regular expressions within command line type syntax
by Thelonius (Priest) on Jun 06, 2003 at 16:24 UTC
    The shell doesn't have regexes, only globs, which are much more limited. You need to look at the manual (or man page) for your particular shell, since there is some difference (e.g. some shells will expand a.{c,o} and some won't).

    However, you can use Perl to feed a list of file names to tar. You can opendir, grep, and then pipe the list to tar. Something like this (untested):

    opendir DIR, $logs or die "Cannot open dir $logs: $!\n"; my @files = grep /^access_log\.\d+\.gz$/, readdir DIR; close DIR; open TAR, "|tar -czpf $target_file - >savetarout" or die "Cannot open tar: $!\n"; print TAR $_, "\n" for @files; close TAR or die "error closing TAR: $!\n";
    Update: the print line should be
    print TAR "$logs/$_\n" for @files;
Re: Acceptable regular expressions within command line type syntax
by sauoq (Abbot) on Jun 06, 2003 at 16:29 UTC
    I'm relatively comfortable using perl's regex language, but have a feeling that command line items speak a different form of the regex-speak.

    No, Perl stays the same whether it is on the command line or in a script.

    But a line like:
    open(TAR,"tar -czpf $target_file $logs/access_log\.d+\.gz |");

    Well, that line looks pretty broken to me. You can't just use a regex anywhere... In your first example, your regex was clearly sitting in the match operator. In this example, it is just sitting in a string. It looks like you are hoping perl will search the directory for you and return the files that match. It won't. You'll have to do that yourself.1

    By the way, Perl doesn't change on the command line, but how you have to quote things sometimes does. That doesn't have anything to do with perl actually. It stems from the fact that the shell is between you and perl.

    On *nix systems, you'll want to use single quotes. Perl variables inside double quotes can look like variables to your shell. Backwhacks in double quotes are also recognized escapes by your shell. You can put anything in single quotes except more single quotes. If you find yourself really needing single quotes in your perl code on the command line, you can use perl's q() operator.

    1. Or, as others have pointed out, let the shell do it for you.

    -sauoq
    "My two cents aren't worth a dime.";
    
Re: Acceptable regular expressions within command line type syntax
by broquaint (Abbot) on Jun 06, 2003 at 16:15 UTC
    That's shell glob expansion (not regex matching), so what you'll want is something like this
    open(TAR,"tar -czpf $target_file $logs/access_log.[0-9]*.gz |");
    Which is roughly equivalent to $logs/access_log\.\d+\.gz in regex.
    HTH

    _________
    broquaint

Re: Acceptable regular expressions within command line type syntax
by Hagbone (Monk) on Jun 06, 2003 at 16:56 UTC
    You need to look at the manual (or man page) for your particular shell, since there is some difference (e.g. some shells will expand a.{c,o} and some won't

    As is often the case, when explained, the obvious seems so ... obvious

    What I wasn't grasping, I believe, is that in my example, I'm need to use available _wildcards_ available from my (bash) shell. And if the widlcards aren't robust enough, then adapt some perl to feed the correct info.

    In my case, I believe the earlier suggestion:

    open(TAR,"tar -czpf $target_file $logs/access_log.[0-9]*.gz |");
    will do the trick

    Thanks all .....

      In my case, I believe the earlier suggestion:
      open(TAR,"tar -czpf $target_file $logs/access_log.[0-9]*.gz |");
      will do the trick.
      While it will probably do the trick, be aware that it is not equivalent. It will also match, e.g. "access_log.20dontsave.gz".

      A glob of access_log.[0-9]*.gz is equivalent to a regex of /^access_log\.\d.*\.gz$/

Re: Acceptable regular expressions within command line type syntax
by hardburn (Abbot) on Jun 06, 2003 at 16:15 UTC

    You're actually passing a string to open(). Perl doesn't expand regex specials like \d in a string.

    ----
    I wanted to explore how Perl's closures can be manipulated, and ended up creating an object system by accident.
    -- Schemer

    Note: All code is untested, unless otherwise stated

Re: Acceptable regular expressions within command line type syntax
by pzbagel (Chaplain) on Jun 06, 2003 at 16:17 UTC

    Well, to begin with, in your second example, you don't put a \ before the d+. But let's assume that you meant to: The trick to this is to realize that the shell does not interpolate single quotes(') just like perl so always remember to do this:

    perl -le '$PATH="test"; print $PATH' #outputs: test

    rather than:

    perl -le "$PATH='test'; print $PATH" #which gives and error when it interpolates $PATH to the #environment variable in the assignment operator

    HTH

    Addendum: Strike that, too early in the morning, can't regex just anywhere like other's have stated. The rest is valid and possibly useful even.