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

hi, I was wondering and even took a fast look at perlopentut and perldoc -f open, but didnt found something to just grep over file inside perl script w/o first opening the file, grepping and then closing (which sometimes is boring)..
Example, currently I often use something in the lines of :
my $line = qx{grep "^ARGV[0]\|" filename.txt}
So that I dont do :
open FILE, .... or die "blah...:$!"; ..grep it... close FILE;
do u get the idea..shortcuts :").. it there something in the core-packges that will work like this...
yep i know i can make it like sub(), but the idea was to just write and forget and not forking grep...

tia

Replies are listed 'Best First'.
Re: quick "open->close" file
by davorg (Chancellor) on Aug 06, 2003 at 11:50 UTC

    If (as your example implies) the filename is passed as the first command line argument, then you can use the empty file input operator (<>) to read from it.

    my @found = grep { something } <>;
    --
    <http://www.dave.org.uk>

    "The first rule of Perl club is you do not talk about Perl club."
    -- Chip Salzenberg

      nope, the filename is not passed in @ARGV.. what comes in @ARGV is for what to search in files..
        the filename is not passed in @ARGV

        Of course there's nothing to stop you putting it there :)

        my @args = @ARGV; @ARGV = 'filename.txt'; my @found = grep { /^args[0]/ } <>;
        --
        <http://www.dave.org.uk>

        "The first rule of Perl club is you do not talk about Perl club."
        -- Chip Salzenberg

Re: quick "open->close" file
by broquaint (Abbot) on Aug 06, 2003 at 12:25 UTC
    Or if you want to perform this on an arbitrary file
    use IO::File; my $line = -f $file and grep { ... } IO::File->new($file)->get_lines;
    So if $file exists, create a temporary IO::File object and read its contents. Not as robust as the <> solution, but it does perform an open/read/close.
    HTH

    _________
    broquaint

      Minor correction: Replace "get_lines" with "getlines".
      use IO::File;
      my $line = -f $file and grep { ... } IO::File->new($file)->getlines;
      
Re: quick "open->close" file
by Aristotle (Chancellor) on Aug 06, 2003 at 15:15 UTC
    Lazy solution causing the whole file to be slurped up front:
    my @match = do { open my $fh, '<', $file or die "$!"; grep /^$ARGV[0]\|/, <$fh>; };
    If your file is large, it takes more effort.
    my @match; { open my $fh, '<', $file or die "$!"; local $_; my $rx = qr/^$ARGV[0]\|/ m/$rx/ && push @match, $_ while <$fh>; }
    If I need the latter more than once, I'd probably factor it out:
    sub grep_file { my ($rx, $file) = @_; my @match; local $_; open my $fh, '<', $file or die "$!"; my $rx = qr/^$rx\|/ m/$rx/ && push @match, $_ while <$fh>; @match; }; my @match = grep_file($ARGV[0], $file);

    Makeshifts last the longest.