How can I get awk to process a BEGIN block for every file that it parses?

I have an awk script that I run against a couple of files. I call it this way:

awk -f script.awk file1 file2

script.awk looks something like this:

 BEGIN {FS=":"} { if( NR == 1 ) { var=$2 FS=" " } else print var,"|",$0 } 

The first line of each file is separated by colons. for every other line, I want it to return to the default file separator by default.

this works fine for the first file, but fails because FS not reset before : after each file, because the BEGIN block is processed only once.

TL; DR: is there a way to get awk to process a BEGIN block once for each file it transfers?

I run this on cygwin bash, if that matters.

+4
source share
3 answers

If you are using gawk version 4 or later, use the BEGINFILE block. From the manual:

BEGINFILE and ENDFILE are additional special templates whose bodies are executed before reading the first record of each input command-line file and after reading the last record of each file. In the BEGINFILE PAGE rule, the ERRNO value will be an empty string if the file can be opened successfully. Otherwise, there is some problem with the file, and the code must use the following file to skip it. If this is not done, gawk generates it as a regular fatal error for files that cannot be opened.

For instance:

 touch abc awk 'BEGINFILE { print "Processing: " FILENAME }' abc 

Output:

 Processing: a Processing: b Processing: c 
+6
source

The FNR variable should do the trick for you. It is similar to NR , except that it is limited inside the file, so it is reset to 1 for each input file.

http://unstableme.blogspot.ca/2009/01/difference-between-awk-nr-and-fnr.html
http://www.unix.com/shell-programming-scripting/46931-awk-different-between-nr-fnr.html

+3
source

Instead:

 BEGIN {FS=":"} 

using:

 FNR == 1 {FS=":"} 
+3
source

Source: https://habr.com/ru/post/1434024/


All Articles