while grep filehandle

Discussion in 'Perl Misc' started by incognito, Jun 18, 2004.

  1. incognito

    incognito Guest

    Unix command line:

    grep Results File.txt

    Returns lots of lines:

    Results = 1
    Results = 11
    Results = 2

    etc, etc, etc.

    Perl script:

    #!/usr/bin/perl

    open (IN, "< File.txt");

    while ( grep /Results/, <IN> ) {
    print "$_\n";
    }

    close (IN);

    Returns nothing. Why?
    incognito, Jun 18, 2004
    #1
    1. Advertising

  2. incognito

    Paul Lalli Guest

    On Fri, 18 Jun 2004, incognito wrote:

    > Unix command line:
    >
    > grep Results File.txt
    >
    > Returns lots of lines:
    >
    > Results = 1
    > Results = 11
    > Results = 2
    >
    > etc, etc, etc.
    >
    > Perl script:
    >
    > #!/usr/bin/perl
    >
    > open (IN, "< File.txt");
    >
    > while ( grep /Results/, <IN> ) {
    > print "$_\n";
    > }
    >
    > close (IN);
    >
    > Returns nothing. Why?
    >



    Basically because you're not using grep correctly. You're using grep in
    the condition to a while. That means you're using it in scalar context.
    In a scalar context, grep returns the number of times its condition
    statement (in this case: /Results/ ) returned true. $_ is never set
    within the while loop.

    What you want is to return the lines that grep matched correctly:

    my @lines = grep /Results/, <IN>;
    print @lines;

    Or even just:

    print grep /Results/, <IN>;

    If you're going to use a while loop, you shouldn't be using grep:

    while (<IN>){
    print if /Results/;
    }


    Or you could just simplify this into a oneliner:

    perl -ne 'print if /Results/' File.txt


    By the way, I'm pretty sure if you had enabled warnings, you would have
    gotten an uninitialize variable warning for the $_ inside the while loop.
    That would have given you a clue as to what was going wrong. Please
    enable warnings in the future before posting.

    Paul Lalli
    Paul Lalli, Jun 18, 2004
    #2
    1. Advertising

  3. incognito

    Juha Laiho Guest

    (incognito) said:
    >#!/usr/bin/perl
    >
    >open (IN, "< File.txt");
    >
    > while ( grep /Results/, <IN> ) {
    > print "$_\n";
    > }
    >
    >close (IN);
    >
    >Returns nothing. Why?


    My brain fails as to why the above doesn't work, but I tried the
    following and it looks ok (though didn't test with a big input
    file):

    #!/usr/bin/perl
    use warnings;
    use strict;

    open (IN, "< File.txt");
    print grep /Results/, <IN>;
    close (IN);
    --
    Wolf a.k.a. Juha Laiho Espoo, Finland
    (GC 3.0) GIT d- s+: a C++ ULSH++++$ P++@ L+++ E- W+$@ N++ !K w !O !M V
    PS(+) PE Y+ PGP(+) t- 5 !X R !tv b+ !DI D G e+ h---- r+++ y++++
    "...cancel my subscription to the resurrection!" (Jim Morrison)
    Juha Laiho, Jun 18, 2004
    #3
  4. incognito

    Paul Lalli Guest

    On Fri, 18 Jun 2004, Juha Laiho wrote:

    > (incognito) said:
    > >#!/usr/bin/perl
    > >
    > >open (IN, "< File.txt");
    > >
    > > while ( grep /Results/, <IN> ) {
    > > print "$_\n";
    > > }
    > >
    > >close (IN);
    > >
    > >Returns nothing. Why?

    >
    > My brain fails as to why the above doesn't work,


    read perldoc -f grep to understand what grep does in a scalar context.

    > but I tried the
    > following and it looks ok (though didn't test with a big input
    > file):
    >
    > #!/usr/bin/perl
    > use warnings;
    > use strict;
    >
    > open (IN, "< File.txt");
    > print grep /Results/, <IN>;
    > close (IN);


    This is correct, because the print unary operator takes a list, so grep
    here is being called in a list context.

    Note that this will be a memory hog for large files, because all lines
    will be read and stored, rather than one at a time. If this is a concern,
    it is better written as:
    while (<IN>){
    print if /Results/;
    }


    See my other post in this thread for the method of doing this in a perl
    one-liner.

    Paul Lalli
    Paul Lalli, Jun 18, 2004
    #4
  5. incognito

    Joe Smith Guest

    Juha Laiho wrote:

    >> while ( grep /Results/, <IN> ) {
    >> print "$_\n";
    >> }

    >
    > My brain fails as to why the above doesn't work,


    There's a big difference between
    foreach ( grep /Results/, <IN>) { print }
    and
    while ( grep /Results/, <IN>) { print }

    -Joe
    Joe Smith, Jun 18, 2004
    #5
  6. incognito

    Web Surfer Guest

    [This followup was posted to comp.lang.perl.misc]

    In article <>,
    says...
    > Unix command line:
    >
    > grep Results File.txt
    >
    > Returns lots of lines:
    >
    > Results = 1
    > Results = 11
    > Results = 2
    >
    > etc, etc, etc.
    >
    > Perl script:
    >
    > #!/usr/bin/perl
    >
    > open (IN, "< File.txt");
    >
    > while ( grep /Results/, <IN> ) {
    > print "$_\n";
    > }
    >
    > close (IN);
    >
    > Returns nothing. Why?
    >


    You are not using grep correctly. The result returned by grep is not a
    TRUE/FALSE value intended to be used as a logical test in a conditional
    statement, but rather is an array containing the matched entries.


    #!/usr/bin/perl

    use warnings;
    use strict;

    my ( $filename , @matches );

    $filename = "File.txt";
    open(IN,"<$filename") or
    die("Can't open $filename : $!\n");

    @matches = grep(/Results/,<IN>);
    close IN;
    print @matches;

    exit 0;
    Web Surfer, Jun 19, 2004
    #6
  7. incognito

    Ben Morrow Guest

    Quoth Web Surfer <>:
    > [This followup was posted to comp.lang.perl.misc]


    I know, that's where I read it.

    > You are not using grep correctly. The result returned by grep is not a
    > TRUE/FALSE value intended to be used as a logical test in a conditional
    > statement, but rather is an array containing the matched entries.


    In list context, yes; in scalar context, grep returns the number of
    matches, which when treated as a boolean gives if there were any at all.

    Ben

    --
    Joy and Woe are woven fine,
    A Clothing for the Soul divine William Blake
    Under every grief and pine 'Auguries of Innocence'
    Runs a joy with silken twine.
    Ben Morrow, Jun 19, 2004
    #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. Eduard W. Lohmann
    Replies:
    1
    Views:
    628
  2. Bill

    key as filehandle error

    Bill, Sep 1, 2004, in forum: Perl
    Replies:
    2
    Views:
    524
  3. Christopher Reeve
    Replies:
    1
    Views:
    456
    Kevin Goodsell
    Sep 14, 2003
  4. Jorge Godoy
    Replies:
    2
    Views:
    250
    Jorge Godoy
    Oct 14, 2003
  5. Wijaya Edward
    Replies:
    1
    Views:
    234
    Marc 'BlackJack' Rintsch
    Oct 26, 2006
Loading...

Share This Page