Can anyone explain this code?

Discussion in 'Perl Misc' started by PerlNovice, Sep 1, 2006.

  1. PerlNovice

    PerlNovice Guest

    I would really appreciate it if someone could explain this code?

    perl -ne 'open F,">".(join"_",@F).".log" or die "@F $!" if
    @F=/(\d+)\s+(\w+)\s+(\d+)\s+(\d\d):(\d\d):(\d\d).*MATCHED/; $m{$2}=$1
    if /(\d+)\s+(?=(.))(MATCHED|DUPLICATE|RESIDUAL)/; END{printf F "MATCHED
    DUPLICATE RESIDUAL\n%-7d %-9d %-7d\n",@m{qw(M D R)}}' INPUTFILE

    I understand parts of it but not all. I can't find help on what the -ne
    stands for. Any pointers to where I can go on the internet to find
    meaning of this would be appreciated.
    PerlNovice, Sep 1, 2006
    #1
    1. Advertising

  2. PerlNovice

    Guest

    PerlNovice wrote:
    > I understand parts of it but not all. I can't find help on what the -ne
    > stands for. Any pointers to where I can go on the internet to find
    > meaning of this would be appreciated.


    You don't need the internet:

    perldoc perlrun

    --
    David Filmer (http://DavidFilmer.com)
    , Sep 1, 2006
    #2
    1. Advertising

  3. PerlNovice

    PerlNovice Guest

    wrote:
    > PerlNovice wrote:
    > > I understand parts of it but not all. I can't find help on what the -ne
    > > stands for. Any pointers to where I can go on the internet to find
    > > meaning of this would be appreciated.

    >
    > You don't need the internet:
    >
    > perldoc perlrun
    >
    > --
    > David Filmer (http://DavidFilmer.com)


    This just gives me explanation of perl -ne
    and nothing else.
    PerlNovice, Sep 1, 2006
    #3
  4. PerlNovice

    Guest

    PerlNovice wrote:
    > This just gives me explanation of perl -ne
    > and nothing else.


    Well, that's the only thing that you specifically asked about.

    You indicated that you already understood other parts of it, so it
    doesn't seem necessary to walk through the code and explain it
    statement-by-statement. Since I'm not a mind-reader (like Tad), I
    don't know which other statements are causing you confusion.

    Of course, looking at the code all crammed together like that is bound
    to add to anyone's confusion (except maybe Abigail). You might want to
    run it through perltidy before trying to mentally parse it:

    open F, ">" . ( join "_", @F ) . ".log"
    or die "@F $!"
    if @F = /(\d+)\s+(\w+)\s+(\d+)\s+(\d\d):(\d\d):(\d\d).*MATCHED/;
    $m{$2} = $1
    if /(\d+)\s+(?=(.))(MATCHED|DUPLICATE|RESIDUAL)/;

    END {
    printf F "MATCHED
    DUPLICATE RESIDUAL\n%-7d %-9d %-7d\n", @m{qw(M D R)};
    }

    Ah, that's better. That makes it easier to parse and easier to ask for
    clarification about some particular aspect of the code.

    --
    David Filmer (http://DavidFilmer.com)
    , Sep 1, 2006
    #4
  5. PerlNovice

    PerlNovice Guest

    Thank you David, Chris and Michele for your responses. This is what I
    understand and this is what I don't understand.

    Please correct me if I am wrong:

    -n : Loop around the code after the space for as many file names as has
    been provided. In my example, just 1.
    -e: This is telling the compiler that a one line script is being
    entered at the command line.
    ': Beginning of the code to be executed
    open F,: Open a file with file handle F followed by separator between 2
    arguments of filename

    Of the rest, I only understand bits. for example,
    @F: An arrary named F. This is defined later.
    printf F "MATCHED DUPLICATE RESIDUAL\n%-7d %-9d %-7d\n": Printing a
    line to the newly created file sandwiched between 2 newline characters
    ; : I know they are end of line characters
    or die: If the file is not found then send a file not found message to
    stdout

    Here are the pieces I don't understand:

    1),">".(join"_",@F).".log" or die "@F $!"
    2)if @F=/(\d+)\s+(\w+)\s+(\d+)\s+(\d\d):(\d\d):(\d\d).*MATCHED/
    3)$m{$2}=$1 if /(\d+)\s+(?=(.))(MATCHED|DUPLICATE|RESIDUAL)/
    4)@m{qw(M D R)}}

    I would appreciate any explanations and any comments from anyone.
    Thanks.
    PerlNovice, Sep 1, 2006
    #5
  6. PerlNovice

    PerlNovice Guest

    One more thing. I want to put this in a file called MyProc.sh and
    execute like this:

    perl -ne MyProc.sh

    What do I need to do that?

    Thanks.
    PerlNovice, Sep 1, 2006
    #6
  7. PerlNovice

    Joe Smith Guest

    PerlNovice wrote:

    > 1),">".(join"_",@F).".log" or die "@F $!"
    > 2)if @F=/(\d+)\s+(\w+)\s+(\d+)\s+(\d\d):(\d\d):(\d\d).*MATCHED/


    The following is not an exact translation,
    but should help you understand.

    # Expecting input like "1 Sept 2006 01:23:45 some text MATCHED"
    @F=/(\d+)\s+(\w+)\s+(\d+)\s+(\d\d):(\d\d):(\d\d).*MATCHED/;
    if (@F) {
    $filename = "$F[0]_$F[1]_$F[2]_$F[3]_$F[4]_$F[6].log";
    open F,'>',$filename or die "$filename $!";
    }

    > 3)$m{$2}=$1 if /(\d+)\s+(?=(.))(MATCHED|DUPLICATE|RESIDUAL)/


    $m{M} = $1 if /(\d+)\s+MATCHED/;
    $m{D} = $1 if /(\d+)\s+DUPLICATE/;
    $m{R} = $1 if /(\d+)\s+RESIDUAL/;

    > 4)@m{qw(M D R)}}


    printf ".....",$m{M},$m{D},$m{R};

    -Joe
    Joe Smith, Sep 2, 2006
    #7
  8. On 2006-09-01 22:09, PerlNovice <> wrote:
    > Thank you David, Chris and Michele for your responses. This is what I
    > understand and this is what I don't understand.
    >
    > Please correct me if I am wrong:
    >
    > -n : Loop around the code after the space for as many file names as has
    > been provided. In my example, just 1.


    No it loops around every *line* in the files.

    > -e: This is telling the compiler that a one line script is being
    > entered at the command line.
    > ': Beginning of the code to be executed


    Actually, the single quotes are to prevent the shell from messing with
    the script. The shell will take everything within the single quotes
    unaltered and pass it as a single argument to perl.

    > open F,: Open a file with file handle F followed by separator between 2
    > arguments of filename
    >
    > Of the rest, I only understand bits. for example,
    > @F: An arrary named F. This is defined later.
    > printf F "MATCHED DUPLICATE RESIDUAL\n%-7d %-9d %-7d\n": Printing a
    > line to the newly created file sandwiched between 2 newline characters
    > ; : I know they are end of line characters
    > or die: If the file is not found then send a file not found message to
    > stdout
    >
    > Here are the pieces I don't understand:
    >
    > 1),">".(join"_",@F).".log" or die "@F $!"


    That's not one piece, that's two pieces. Everything before the "or"
    belongs to the open before it. Since it's a bit useless to talk about
    pieces of code which were cut apart at random places, I've sent the
    complete script through Deparse:

    perl -MO=Deparse -ne 'open F,">".(join"_",@F).".log" or die "@F $!" if @F=/(\d+)\s+(\w+)\s+(\d+)\s+(\d\d):(\d\d):(\d\d).*MATCHED/; $m{$2}=$1 if /(\d+)\s+(?=(.))(MATCHED|DUPLICATE|RESIDUAL)/; END{printf F "MATCHED DUPLICATE RESIDUAL\n%-7d %-9d %-7d\n",@m{qw(M D R)}}' INPUTFILE

    results in:

    LINE: while (defined($_ = <ARGV>)) {
    open F, '>' . join('_', @F) . '.log' or die "@F $!" if @F = /(\d+)\s+(\w+)\s+(\d+)\s+(\d\d):(\d\d):(\d\d).*MATCHED/;
    $m{$2} = $1 if /(\d+)\s+(?=(.))(MATCHED|DUPLICATE|RESIDUAL)/;
    sub END {
    printf F "MATCHED DUPLICATE RESIDUAL\n%-7d %-9d %-7d\n", @m{'M', 'D', 'R'};
    }
    ;
    }

    Now let's move the END block to the end where it belongs:

    LINE: while (defined($_ = <ARGV>)) {
    open F, '>' . join('_', @F) . '.log' or die "@F $!" if @F = /(\d+)\s+(\w+)\s+(\d+)\s+(\d\d):(\d\d):(\d\d).*MATCHED/;
    $m{$2} = $1 if /(\d+)\s+(?=(.))(MATCHED|DUPLICATE|RESIDUAL)/;
    }
    printf F "MATCHED DUPLICATE RESIDUAL\n%-7d %-9d %-7d\n", @m{'M', 'D', 'R'};

    and rearrange the if statements in the loop:

    LINE: while (defined($_ = <ARGV>)) {
    if (@F = /(\d+)\s+(\w+)\s+(\d+)\s+(\d\d):(\d\d):(\d\d).*MATCHED/) {
    open F, '>' . join('_', @F) . '.log'
    or die "@F $!"
    }
    if (/(\d+)\s+(?=(.))(MATCHED|DUPLICATE|RESIDUAL)/) {
    $m{$2} = $1
    }
    }
    printf F "MATCHED DUPLICATE RESIDUAL\n%-7d %-9d %-7d\n", @m{'M', 'D', 'R'};

    Is it clearer now? You may have to read
    perldoc perlsyn
    perldoc perlvar
    perldoc perlre
    perldoc -f open
    perldoc perldata
    to understand what's going on.
    (and to to really understand what it's supposed to do you also need to
    know what the file that is read looks like).

    BTW, while perl golf and obfuscations are lots of fun and educational,
    I don't think it gains you much if you don't even understand basic perl
    constructs yet. Start with perl code that's written to be readable, not
    as short as possible.

    hp

    --
    _ | Peter J. Holzer | > Wieso sollte man etwas erfinden was nicht
    |_|_) | Sysadmin WSR | > ist?
    | | | | Was sonst wäre der Sinn des Erfindens?
    __/ | http://www.hjp.at/ | -- P. Einstein u. V. Gringmuth in desd
    Peter J. Holzer, Sep 2, 2006
    #8
  9. PerlNovice

    PerlNovice Guest

    Michele/David, I put David's tidied up version in a file called
    MyProc.pl. I then tried
    to execute it and see if it produces the same resul as follows:

    perl -ne MyProc.pl

    Nothing happens. It doesn't even come back to command prompt.

    Joe, thank you for your response. However, I would need little bit more
    detail to understand.

    1),">".(join"_",@F).".log" or die "@F $!"
    I know the part after the comma is the second part of the file handle.
    But what does
    ">".(join"_",@F).".log" mean? I know the file being created is a .log
    file. What is
    ">".(join"_",@F).? I know @F is the file name that is created later.
    How is the file name
    created in this format? What d,s,w etc mean? What .*MATCHED? I know
    that giving a character
    by character explanation will take you long time but any explanation in
    this format will be
    very helpful. In the meantime, I am trying by best to understand the
    code.

    A lot of thanks to anyone who responds.
    PerlNovice, Sep 3, 2006
    #9
  10. PerlNovice <> wrote:

    > perl -ne MyProc.pl
    >
    > Nothing happens.



    The -n switch makes a while-diamond loop.

    Since you did not call the program with any command line arguments
    the diamond operator will (attempt to) read from STDIN.


    > It doesn't even come back to command prompt.



    Because it is waiting for you to type some data on STDIN...


    > But what does
    > ">".(join"_",@F).".log" mean?



    perldoc -f join

    The concatentation operator is described in:

    perldoc perlop


    > What d,s,w etc mean?



    That depends on where d,s,w etc appear in the code.

    Those characters do not appear in any code that you've quoted,
    so I dunno what they do...


    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
    Tad McClellan, Sep 3, 2006
    #10
    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. renata
    Replies:
    1
    Views:
    781
    Kevin Spencer
    Jun 25, 2003
  2. =?Utf-8?B?QW5kcmV3?=

    Could anyone explain this Yahoo! source code?

    =?Utf-8?B?QW5kcmV3?=, May 4, 2006, in forum: ASP .Net
    Replies:
    1
    Views:
    820
    Karl Seguin [MVP]
    May 4, 2006
  3. C++fan
    Replies:
    14
    Views:
    730
    C++fan
    Jan 5, 2004
  4. Sid
    Replies:
    3
    Views:
    427
  5. Jia Lu
    Replies:
    1
    Views:
    269
    Gabriel Genellina
    Feb 11, 2007
Loading...

Share This Page