Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW
 
PerlMonks  

Line number in a file

by ciryon (Sexton)
on Jul 06, 2004 at 08:21 UTC ( [id://372037]=perlquestion: print w/replies, xml ) Need Help??

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

Hi Monks! I'm investigating a file, matching and extracting interesting stuff. I split the file several times so it's not intact during my operations. Now I want to know the line number where I extracted something. Is it possible to get this without having to use some kind of counter? An example to illuminate my problem further:
if(/(\S+)\s+(\d+)/) { $mylist{$1} = $2; }
This is one of the regexes I use to store values in a list. Is it at this point possible to get the line number where I got the match? I have the filename as a variable, but when I match $_ isn't the entire file, but a small part of it. Thanks!

Update: I read the file with

while (<MYFILE>) { $alldata .= $_ ; }
Newlines aren't important when going through the data.

Replies are listed 'Best First'.
Re: Line number in a file
by pelagic (Priest) on Jul 06, 2004 at 08:36 UTC
    Your code doesn't show how you process your file initially but maybe you don't know the special variable $.
    while (<FILE>) { if (/what not/) { print "We found what not in line $.\n"; } }
    more info perlvar

    pelagic
Re: Line number in a file
by davidj (Priest) on Jul 06, 2004 at 09:04 UTC
    You might consider this a nitpick, but the replies by pelagic and busunsl need a clarification.

    To the best of my knowledge, the built-in Perl variable $. is technically the record number variable, not the line number variable, and a record is not always a line. It all depends upon the value of $/, the record separator variable. By default it is newline, but it can be changed.

    I mention this only because I once had a terrible time debugging a (poorly written) script which read from a file, used $., and the script writer had changed the value of $/. It took me some time to figure that out.

    davidj
      >    It all depends upon the value of $/, the record separator variable.
      Of course if you read a file in slurp mode you actually just read 1 record and the official name INPUT_LINE_NUMBER is somewhat misleading because lines become a logical measure.
      And if you set $/ to some weird separator the meaning of line is actually set to something completely different.

      pelagic
      the script writer had changed the value of $/.
      I hope you berated gave him a "talking to" about not using local (appropriately).
        Well, I was considering requesting that his Perl privileges be temporarily suspended, but then, how could he learn to write better code. So, instead, I smacked him on the head with the Camel book :)

        davidj
Re: Line number in a file
by busunsl (Vicar) on Jul 06, 2004 at 08:37 UTC
    When you read the file line by line, $. will give you the current linenumber. If you just slurp it, you'll have to set up a counter.
Re: Line number in a file
by edan (Curate) on Jul 06, 2004 at 09:58 UTC

    I think the others have answered your question about how to get the line number in the file-reading loop using $.. But your question also seems to be "How do I save off the value for later use?" Maybe I'm misunderstanding the question, or maybe my answer is blindingly obvious to you once you know about $., but here is an example (using your own example code) of how you might save off that info for later use when you process the data you collected:

    while (<MYFILE>) { $alldata .= $_ ; if(/(\S+)\s+(\d+)/) { $mylist{$1} = {value => $2, linenum => $. }; } }

    You see that instead of just saving off the right-hand value ($2) as a scalar value in the (badly-named) hash %mylist, the value is a hash-reference which contains the value and the line-number it was found on. You would then access the values along the lines of:

    for my $key ( keys %mylist ) { my $value = $mylist{$key}{value}; my $linenum = $mylist{$key}{linenum}; print "$key has value $value, found on line $linenum\n"; }

    HTH

    --
    edan

Re: Line number in a file
by ysth (Canon) on Jul 06, 2004 at 09:45 UTC
    Newlines aren't important when going through the data.
    Yes, they are; they determine the line number you say you want :)

    You are going to have to somehow keep track of them. Are the small parts of $_ you are working with handled consecutively? If so, you can just add up the newlines in each section as you finish working with it: $linenumber += y/\n//;

Re: Line number in a file
by Jasper (Chaplain) on Jul 06, 2004 at 10:44 UTC
    If you're splitting $_ several times before you get to matching the bit you want, the y/\n//c or matching $` for \n methods aren't going to work. I'd suggest prepending the line number (assuming you haven't changed $\ ;) ) when reading the file:
    while (<FILE>) { s/^/[$.]/; $file .= $_; }
    then do:
    if(/(^\[(\d+)\](\S+)\s+(\d+)/m) { $mylist{$2} = $3; $linenumber = $1; }
    Well, that's probably what I'd do (or something like it, anyway - I'd have to see the data to decide)
Re: Line number in a file
by murugu (Curate) on Jul 06, 2004 at 10:28 UTC

    if $/(input record separator) is '\n',

    use $. which is used to get the current line number.

    for ur problem, use $` and count the number of \n which yields the line number.(But using $` makes program run slow)

    cheers

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://372037]
Approved by broquaint
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others exploiting the Monastery: (3)
As of 2024-04-24 16:08 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found