How to detect EOF in awk?

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

+7
awk eof
Oct 29 '09 at 21:22
source share
11 answers

You have two options, both messy.

  • Save a copy of each current line in the temp variable, and then use the END block to process it.
  • Use the system command to run "wc -l | getline" in a BEGIN block to get the number of lines in a file, and then count this value.

You may need to play a little with No. 2 to run it, but it should work. It has been a while since I did any awk.

+8
Oct 29 '09 at 21:40
source share

The special END template will only match after the end of all input. Please note that this template cannot be combined with any other template.

Probably more useful is the getline pseudo-function, which resets $0 to the next line and returns 1, or in case of returning EOF 0! I think this is what you want.

For example:

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

If you process only one file, this will be equivalent to:

 awk 'END { print "Found EOF" }' 
+8
Oct 29 '09 at 21:41
source share

These are the only reasonable ways to do what you want in the worst order:

 awk 'NR==FNR{max++; next} FNR == max { print "Final line:",$0 }' file file awk -v max="$(wc -l < file)" 'FNR == max { print "Final line:",$0 }' file awk 'BEGIN{ while ( (getline dummy < ARGV[1]) > 0) max++; close(ARGV[1])} FNR == max { print "Final line:",$0 }' file 
+5
Dec 12 '12 at 20:55
source share

EOF detection is not very reliable if there are multiple files on the command line. File start detection is more reliable.

For this, the first file is special, and we ignore FNR == 1.

After the first file, FNR == 1 becomes the end of the previous file. last_filename always has the name of the file you are processing.

Perform file processing after else.

Perform EOF processing inside the else block and in the END block.

  gawk 'BEGIN{last_filename="";} \ FNR==1{if (last_filename==""){last_filename=FILENAME;} \ else {print "EOF: "last_filename;last_filename=FILENAME;}} \ END{print "END: "last_filename;}' $* 

For multiple file sets, the else block is executed in EOF for all but the last file. The last file is executed in the END block.

For single sets of files, the else block is not executed, and the END block is executed.

+4
Feb 18 '14 at 21:44
source share

The gawk implementation has a special rule called ENDFILE , which will be launched after processing each file in the argument list. It works:

 awk '{line=$0} ENDFILE {print line}' files... 

you can find more information here ">

+2
Oct 13 '16 at 12:18
source share

I'm not even sure how to classify 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 nice thing about this hack is that by assigning $0 , all other declarative templates and actions work, one line is delayed. You cannot make them work for END , even if you put END on top, but you have control over the last line and you haven’t done anything for it.

+1
Nov 05 '09 at 1:28
source share

To determine the last line of each file in the argument list, the following works beautifully:

 FNR == 1 || EOF { print "last line (" FILENAME "): " $0 } 
+1
Sep 09 '10 at 17:49
source share

One easy way is to run the file through an intermediate sed script that puts 0 on each not-last line and 1 on the last.

 cat input_file | sed 's/^/0/;$s/0/1/' | awk '{LST=/^1/;$0=substr($0,2)} ... your awk script in which you can use LST to check for the ... last line.' 
+1
Dec 06 '11 at 3:17
source share

The hmm awk END variable tells you when you have already reached EOF . In fact, this does not help you much. I think

0
Oct 29 '09 at 21:27
source share

you can try the following:

 awk 'BEGIN{PFNR=1} FNR==PFNR{PFNR++;next} {print FILENAME,PFNR=2} END{print FILENAME}' file1 file2 
0
Feb 18 '16 at 8:47
source share

The portable solution is provided in the gawk user manual , although, as mentioned in another answer, gawk has BEGINFILE and ENDFILE.

0
Jan 02 '18 at 16:55
source share



All Articles