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

OK, there is a chance I'm just tired and missing something obvious, but this is very strange:

c:\blah> dir 07/10/2008 08:45 PM <DIR> 16 07/10/2008 08:45 PM <DIR> 17 07/10/2008 08:24 PM <DIR> 18 07/10/2008 08:45 PM <DIR> 19 19/03/2009 09:44 AM <DIR> 20- Foo bar bat 30/10/2008 10:25 AM <DIR> 21 Baz bat qux 07/10/2008 08:45 PM <DIR> 22- Shiver me timbers ...
c:\blah> perl -e "for (glob '*') { my ($id) = / (\d+)$/ || /^(\d+)/; print \"$_ => id=$id\n\"; }"

Prints nothing, but CREATES A FILE called 'id' with content:

16 ==1 17 ==1 18 ==1 19 ==1 20- Foo bar bat ==20 21 Baz bat qux ==21 22- Shiver me timbers ==22 23 ==1 ...

What is going on here?

Infos: perl, v5.8.8 built for MSWin32-x86-multi-thread, Binary build 816 [255195] provided by ActiveState


The zeroeth step in writing a module is to make sure that there isn't already a decent one in CPAN. (-- Pod::Simple::Subclassing)

Replies are listed 'Best First'.
Re: Win32 File Creation Weirdness, ActivePerl 5.8.8
by Corion (Patriarch) on Jul 07, 2009 at 08:45 UTC

    Most likely that is a quoting issue between cmd.exe and Perl. I try to avoid double quotes in my oneliners:

    perl -e "for (glob '*') { my ($id) = /(\d+)$/ || /^(\d+)/; print qq($_ + => id=$id\n); }"

    If you want to find out what Perl sees, use B::Deparse:

    >perl -MO=Deparse -e "for (glob '*') { my ($id) = /(\d+)$/ || /^(\d+)/ +; print qq($_ => id=$id\n); }" use File::Glob (); foreach $_ (glob('*')) { my($id) = /(\d+)$/ || /^(\d+)/; print "$_ => id=$id\n"; } -e syntax OK >perl -MO=Deparse -e "for (glob '*') { my ($id) = /(\d+)$/ || /^(\d+)/ +; print \"$_ => id=$id\n\"; }" -e syntax OK >

    So Perl doesn't even want to tell me what's going on with the double-quote thing.

      Many thanks Corion++! That fixed it. :)

      I try to avoid double quotes in my oneliners

      That's good advice. I need to remember to use the special quoting operators! Incidentally, I hate the windows shell.


      The zeroeth step in writing a module is to make sure that there isn't already a decent one in CPAN. (-- Pod::Simple::Subclassing)
Re: Win32 File Creation Weirdness, ActivePerl 5.8.8
by jwkrahn (Abbot) on Jul 07, 2009 at 09:29 UTC

    Your expression:

    my ($id) = /(\d+)$/ || /^(\d+)/;

    will not work correctly because the first regular expression is evaluated in scalar context and so will return 1 when it matches and not the id number.

    This will do what you want:

    my $id = ( /(\d+)$/ )[ 0 ] || ( /^(\d+)/ )[ 0 ];

    Or this:

    my $id = /(\d+)$/ ? $1 : /^(\d+)/ ? $1 : ();

      jwkrahn, I fixed the bug like so after taking a break - I'm rather sleep deprived :|

      my ($id) = /(\d+)$/; unless (defined $id) { ($id) = /^(\d+)/ }

      Windows never ceases to astonish me. Thanks all for your help :)


      The zeroeth step in writing a module is to make sure that there isn't already a decent one in CPAN. (-- Pod::Simple::Subclassing)
        Windows never ceases to astonish me.
        You think that's astonishing? Brace yourself.

        The Windows CLI wants redirection operator characters (e.g.,  > < |) in a double-quoted string to be escaped with a  ^ (hat) character if they are preceded by an odd number of backslash-escaped double-quote characters in the string! (Don't even ask what happens if the backslash escapes are themselves backslash-escaped.)

        Consider (this just illustrates redirection-character escaping; the scalar/list context problem with the regex is not addressed):

        C:\@Work\Perl\junque>dir Volume in drive C has no label. Volume Serial Number is EC11-ED1D Directory of C:\@Work\Perl\junque 07/07/2009 11:42 AM <DIR> . 07/07/2009 11:42 AM <DIR> .. 07/07/2009 11:41 AM <DIR> 16 07/07/2009 11:41 AM <DIR> 17 foo bar 07/07/2009 11:42 AM <DIR> 18- baz quux 0 File(s) 0 bytes 5 Dir(s) 10,227,699,712 bytes free C:\@Work\Perl\junque>perl -e "for (<*>) { my ($id) = /(\d+)$/ || /^(\d+)/; print qq{$_ => \"id=^>$id\" => x \n}; } " 16 => "id=>1" => x 17 foo bar => "id=>17" => x 18- baz quux => "id=>18" => x C:\@Work\Perl\junque>perl -e "for (<*>) { my ($id) = /(\d+)$/ || /^(\d+)/; print qq{$_ => \"id=>$id\" => x \n}; } " The system cannot find the path specified. C:\@Work\Perl\junque>perl -e "print qq{ (\") \n}; for (^<*^>) { my ($id) = /(\d+)$/ ^|^| /^^(\d+)/; print qq{$_ =^> \"id=>$id\" =^> x \n}; } " (") 16 => "id=>1" => x 17 foo bar => "id=>17" => x 18- baz quux => "id=>18" => x x => "id=>" => x
        Enjoy!
Re: Win32 File Creation Weirdness, ActivePerl 5.8.8
by imrags (Monk) on Jul 07, 2009 at 09:11 UTC
    The > operator is redirecting the output to file "id".
    Converting => operator to a letter/word like "and" prints the output without printing the ID
    I'm getting the result without any ID... This will give u a result sans id
    perl -e "for (glob '*') { ($id) = /\d+$/ || /^\d+/; print \"$_\n\"; }"
    You can also try this
    UPDATED CODE(thanks to cdarke):
    perl -e "while (<*>){print $_.\"\n\";}"
    Same result
    Raghu
      Except that <*.*> expects the filename to include a dot. It won't pickup directory names (which generally do not contain a dot) or filenames like README.