Peek at next line, but don't consume it

2020-02-28 02:17发布

getline reads in the next line and increments the NR counter by 1. After using getline, awk resumes work with the next line. This is the desired behavior in most cases.

In my special situation I need only to peek the next line and depending on its content I read the next line or I need to backtrack one line.

How can I backtrack one line in awk? I tried setting the NR counter manually to NR=NR-1 but this doesn't work. Or is there a method that only looks at the next line without changing NR?

I need a lookahead of one line. Simply saving the line in a variable and referring to it later does not work in this case. I am trying to implement a literate programming tool in awk, where a master file might contain many subfiles. Such a subfile begins with a line like "% file:file1". The end of such a file is reached, if a line with a lower indentation or another line with a line like "% file:file2" is reached.

The rule set for all lines matching /% file:/ is not used, when I have already read this line with getline. That's why I would like to reset NR to the previous line, then awk would read the line matching /% file:/ again and the appropriate rule would be executed.

标签: awk gawk
2条回答
姐就是有狂的资本
2楼-- · 2020-02-28 02:46

This is a bit of a hack and is fairly expensive, but for small files does give you a lookahead:

cmd="sed -n " NR + 1 "p " FILENAME; cmd | getline nextline

That will take the current value of NR and use sed to extract line NR + 1 from the input file. This is expensive because sed will read through the entire file each time you do a lookahead (you can alleviate that slightly by adding a 'q' command to sed). The variable nextline will be set to the next line of the file, and will be blank on the last line.

查看更多
太酷不给撩
3楼-- · 2020-02-28 02:55

This may approach what you're looking for and shouldn't be as expensive as the sed solution since AWK maintains a pointer into the file that getline opens.

awk 'FNR == 1 {
         getline nextline < FILENAME
     }
     {
         getline nextline < FILENAME;
         print "currentline is:", $0;
         print "nextline is:   ", nextline
     }' input file

The first block reads the first line and wastes it.

In this form, getline doesn't set any variables such as NR, FNR, NF or $0. It only sets the variable that you supply (nextline in this case).

See this for some additional information.

查看更多
登录 后发表回答