如何在处理前获取AWK中的字段数

如何在处理前获取AWK中的字段数,awk,Awk,我想在awk脚本的BEGIN部分为文件创建一个头,但要做到这一点,我需要知道有多少字段。我可以在main部分中进行检查,以检查NR==1,但这将在每一行上进行评估,从而降低速度 下面是我使用一行的尝试 fields.txt a 1 b 2 c 3 结果: awk 'NR==1{a=NF; print "before begin, there are ", a, "fields"}BEGIN{print "there are ", a, "fields"}{print a"\t"$0

我想在awk脚本的
BEGIN
部分为文件创建一个头,但要做到这一点,我需要知道有多少字段。我可以在main部分中进行检查,以检查
NR==1
,但这将在每一行上进行评估,从而降低速度

下面是我使用一行的尝试

fields.txt

a   1
b   2
c   3
结果:

awk 'NR==1{a=NF; print "before begin, there are ", a, "fields"}BEGIN{print "there are ", a, "fields"}{print a"\t"$0}END{print "there were", a, "fields"}' fields.txt
there are   fields
before begin, there are  2 fields
2   a   1
2   b   2
2   c   3
there were 2 fields
我猜BEGIN块仍然在前面的块之前被计算。我是否真的完成了我的目标,或者,
NR==1
检查仍在每一行上进行评估

编辑 所以,让我们来看看为什么我要用我现在的方式去做

  • 我有一个10万行40列的文件
  • 此文件是管道中另一个进程的输出,awk脚本是最后一步
  • 我正在基于其他行计算两行,并将它们添加到输出中
  • 我希望最后一个文件包含反映两个新添加列的标题

  • 我不确定awk对每行执行
    NR==1
    检查是否真的会让它慢很多。如果这确实是一个问题,那么也许可以在当前
    awk
    脚本之外进行初始字段计数,并将其与变量一起发送到awk脚本中。比如:

    fieldCount=`head -1 fields.txt | awk '{print NF}'`
    awk -v a="$fieldCount" 'BEGIN{print "there are ", a, "fields"}{print a"\t"$0}END{print "there were", a, "fields"}' fields.txt
    

    我不确定awk对每行执行
    NR==1
    检查是否真的会让它慢很多。如果这确实是一个问题,那么也许可以在当前
    awk
    脚本之外进行初始字段计数,并将其与变量一起发送到awk脚本中。比如:

    fieldCount=`head -1 fields.txt | awk '{print NF}'`
    awk -v a="$fieldCount" 'BEGIN{print "there are ", a, "fields"}{print a"\t"$0}END{print "there were", a, "fields"}' fields.txt
    

    听起来这就是你想要做的:

    awk '
      BEGIN {if ((getline < ARGV[1]) > 0) a=NF; print "there are", a, "fields"}
      {print a"\t"$0}
      END {print "there were", a, "fields"}
    ' file
    there are 2 fields
    2       a   1
    2       b   2
    2       c   3
    there were 2 fields
    
    awk'
    开始{if((getline0)a=NF;打印“有”,a,“字段”}
    {打印“\t”$0}
    结束{打印“有”,a,“字段”}
    "档案"
    有两个字段
    2 a 1
    2 b 2
    2 c 3
    有两个字段
    
    但是idk如果考虑到
    NR==1
    检查相对于要对数据执行的任何其他转换的微小性能影响,那么它是值得的


    如果您正在考虑使用它,请确保您阅读并完全理解在中使用
    getline
    的所有含义。

    听起来您正试图这样做:

    awk '
      BEGIN {if ((getline < ARGV[1]) > 0) a=NF; print "there are", a, "fields"}
      {print a"\t"$0}
      END {print "there were", a, "fields"}
    ' file
    there are 2 fields
    2       a   1
    2       b   2
    2       c   3
    there were 2 fields
    
    awk'
    开始{if((getline0)a=NF;打印“有”,a,“字段”}
    {打印“\t”$0}
    结束{打印“有”,a,“字段”}
    "档案"
    有两个字段
    2 a 1
    2 b 2
    2 c 3
    有两个字段
    
    但是idk如果考虑到
    NR==1
    检查相对于要对数据执行的任何其他转换的微小性能影响,那么它是值得的


    如果您正在考虑使用
    getline
    at,请确保您已阅读并完全理解使用它的所有含义。

    BEGIN
    块中
    BEGIN
    发生在输入处理之前,期间。从技术上讲,一个文件没有很多字段(至少从awk的角度来看),只有一行
    NR==1
    是正确的方法,如果你想知道第一行的字段数。你不想检查每一行的字段数吗?是在读取每一行时计算
    NR==1
    还是只计算一次?@karakfa——每一行的字段数都相同,但我事先不知道这个数字。我想创建一个标题,该标题的字段数与其余行的字段数相同。这在
    BEGIN
    块中是不可能的
    BEGIN
    发生在处理输入之前,period。从技术上讲,一个文件没有很多字段(至少从awk的角度来看),只有一行
    NR==1
    是正确的方法,如果你想知道第一行的字段数。你不想检查每一行的字段数吗?是在读取每一行时计算
    NR==1
    还是只计算一次?@karakfa——每一行的字段数都相同,但我事先不知道这个数字。我想创建一个与其余行具有相同字段数的标题。