tags:

views:

968

answers:

5

Is there a way to determine whether the current line is the last line of the input stream?

A: 

Hmm the awk END variable tells when you have already reached the EOF. Isn't really much of help to you I guess

jitter
+2  A: 

You've got two options, both kind of messy.

  1. Store a copy of every current line in a temp variable, and then use the END block to process it.
  2. Use the system command to run "wc -l | getline" in the BEGIN block to get the number of lines in the file, and then count up the that value.

You might have to play with #2 a little to get it to run, but it should work. Its been a while since I've done any awk.

SDGator
Yuck, I really hate that option 2. But option 1 is the way to do it. +1 for option 1.
steveha
A: 

The special END pattern will match only after the end of all input. Note that this pattern can't be combined with any other pattern.

More useful is probably the getline pseudo-function which resets $0 to the next line and return 1, or in case of EOF return 0! Which I think is what you want.

For example:

awk '{ if(getline == 0) { print "Found EOF"} }'

If you are only processing one file, this would be equivalent:

awk 'END { print "Found EOF" }'

uriel
Actually, my first example should read:awk '{ while(getline == 1) {}; print "Found EOF" }'
uriel
Note that getline will return -1 if there's an error.
jamessan
True, forgot to mention that, but if he is reading from a bunch of static files this is unlikely, but then I guess that depends very much on the context of his script.
uriel
A: 

I'm not even sure how to categorize this "solution"

{
    t = lastline
    lastline = $0
    $0 = t
}

/test/ {
    print "line <" $0 "> had a _test_"
}

END {
    # now you have "lastline", it can't be processed with the above statements
    # ...but you can work with it here
}

The cool thing about this hack is that by assigning to $0, all the remaining declarative patterns and actions work, one line delayed. You can't get them to work for the END, even if you put the END on top, but do have control on the last line and you haven't done anything else to it.

DigitalRoss
A: 

To detect the last line of each file in the argument list the following works nicely:

FNR==1 || EOF { print "last line (" FILENAME "): " $0 }

sgr