Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic

moving the filehandle to anyline of a file

by jesuashok (Curate)
on May 02, 2006 at 04:39 UTC ( #546815=perlquestion: print w/replies, xml ) Need Help??
jesuashok has asked for the wisdom of the Perl Monks concerning the following question:

Hi all,

I have a file called "input.txt".
This file contains the 10000 lines in it.
Here my requirement goes,
I want to locate a line a starting with "Confname" as the first few characters
The normal way for doing this task

while ( <FH> ) { if $_ =~ /^Confname/ { ....... } }
If that is the best way to make my File Handle on the line starting with, "Confname", I will go ahead with that.
But if anyone used other than the method, which I have specified, please do write your reply, so that, I can use that in my code.

"Keep pouring your ideas"

Replies are listed 'Best First'.
Re: moving the filehandle to anyline of a file
by davido (Archbishop) on May 02, 2006 at 04:51 UTC

    There was a similar question posted here a few days ago. It boils down to this: Perl cannot know where, within a file, "Confname" occurs, without first skimming through the file to find "Confname". Similarly, it cannot know where line 34 begins, how many characters are in the 3000th line, or any other internal file information, without first skimming through the file to find out.

    This fact is not constrained to Perl. It is true of any programming language, given the same scenario: find "Confname" in a file. It's a fact that is not even constrained to just the world of computers.

    Quick, find me the 23rd occurrence of the word "Radley" in To Kill a Mockingbird, but do so without opening the book, and without skimming your way through the book. It's not possible.

    A good piece of advice when thinking through a problem is to think of how you might do it yourself, without a computer. And then program the computer to do what you would have done. If it were you, yourself, looking for "Confname" in a document, you would physically skim through the document looking for that word.

    That said, your existing snippet is probably the simplest way to do just that. If you find that the simple solution fails to meet your needs in some way, think of how you would improve the situation in the non-computer world. Maybe after you found "Confname" for the first time, in the non-computer world, you would put a bookmark on the proper page of the document. In the computer world, you might maintain an index file to accomplish the same efficiency.



      Thanks a lot for your clear answer. It is very much useful for me and others who wants to do this task.

      "Keep pouring your ideas"
Re: moving the filehandle to anyline of a file
by Hue-Bond (Priest) on May 02, 2006 at 05:01 UTC

    You can also:

    while ($fh) { /^Confname/ or next; work_with $_; last; ## if you want to process only the first ocurrence of such l +ine }

    If the lines in the file are not very long, it may fit in memory:

    my @confnames = grep /^Confname/, <$fh>; ## if you want to process all lines: work_with $_ for @confnames; ## else: work_with $confnames[0];

    Update: Fixed a missing <>. Thanks to Tanktalus!

    David Serrano

Re: moving the filehandle to anyline of a file
by GrandFather (Sage) on May 02, 2006 at 04:54 UTC

    I'd refactor that slightly to:

    while ( <FH> ) { next if $_ !~ /^Confname/; ... }

    DWIM is Perl's answer to Gödel
      Or simply, if we're refactoring,
      while ( <FH> ) { next unless /^Confname/; ... }
      I've always found unless clearer than a negated if for short single-condition conditionals like that. I do accept that that's personal preference, though .. :)

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://546815]
Approved by GrandFather
[thezip]: Whaaaat???

How do I use this? | Other CB clients
Other Users?
Others studying the Monastery: (10)
As of 2017-03-24 18:04 GMT
Find Nodes?
    Voting Booth?
    Should Pluto Get Its Planethood Back?

    Results (305 votes). Check out past polls.