如何让awk处理它解析的每个文件的BEGIN块?

nul*_*ion 5 bash awk cygwin

我有一个awk脚本,我正在对一对文件运行.我这样称呼它:

awk -f script.awk file1 file2

script.awk看起来像这样:

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

每个文件的第一行是冒号分隔的.对于每一行,我希望它返回到默认的空白文件分隔符.

这适用于第一个文件,但失败,因为在每个文件之后FS没有重置:,因为BEGIN块只处理一次.

tldr:有没有办法让awk处理BEGIN块一次为我传递的每个文件?

我在cygwin bash上运行它,以防万一.

Tho*_*hor 8

如果您使用的是gawk版本4或更高版本,那么就是BEGINFILE块.从手册:

BEGINFILE和ENDFILE是附加的特殊模式,它们的主体在读取每个命令行输入文件的第一条记录之前以及在读取每个文件的最后一条记录之后执行.在BEGINFILE规则内,如果文件可以成功打开,则ERRNO的值将为空字符串.否则,文件存在一些问题,代码应使用nextfile跳过它.如果没有这样做,gawk会对无法打开的文件产生通常的致命错误.

例如:

touch a b c
awk 'BEGINFILE { print "Processing: " FILENAME }' a b c
Run Code Online (Sandbox Code Playgroud)

输出:

Processing: a
Processing: b
Processing: c
Run Code Online (Sandbox Code Playgroud)

编辑 - 更便携的方式

正如DennisWilliamson所指出的,你可以FNR == 1在脚本的开头实现类似的效果.除此之外,您可以FS直接从命令行进行更改,例如:

awk -f script.awk FS=':' file1 FS=' ' file2
Run Code Online (Sandbox Code Playgroud)

这里FS变量将保留以前的任何值.

  • 如果你正在使用`gawk`*4*. (2认同)