Unix AWK打印FNR从0递增

Unix AWK打印FNR从0递增,unix,awk,Unix,Awk,这是我试图添加最后一个参数的脚本,它将FNR打印到第四个字段中 #!/usr/bin/awk -f { sub(/\r$/,"") } /^BEGIN_DATA_FORMAT/{ getline for (i=1;i<=NF;i++) if ($i~/LAB/) a[i]=$i } /^BEGIN_DATA$/,/^END_DATA$/{ s=

这是我试图添加最后一个参数的脚本,它将FNR打印到第四个字段中

#!/usr/bin/awk -f

{ sub(/\r$/,"") }

/^BEGIN_DATA_FORMAT/{
        getline
            for (i=1;i<=NF;i++) 
                    if ($i~/LAB/) a[i]=$i
                }


/^BEGIN_DATA$/,/^END_DATA$/{
             s="";
             if (NF<2) next; else 
                for (j in a)
            s=s?s"\t"$j:$j
            print s 
            }
48.34   -55.88  19.19   (Untitled 0)
26.95   24.36   13.43   (Untitled 1)
25.53   4.45    -20.68  (Untitled 2)
71.27   6.68    24.28   (Untitled 3)
...
这是我的第二个脚本:

#!/usr/bin/awk -f

{ OFS = "\t"; $4="(Untitled "FNR-1")"; print $0 }
将第一个脚本管道化到第二个脚本将返回预期结果,FNR从第四个字段中的0开始

#!/usr/bin/awk -f

{ sub(/\r$/,"") }

/^BEGIN_DATA_FORMAT/{
        getline
            for (i=1;i<=NF;i++) 
                    if ($i~/LAB/) a[i]=$i
                }


/^BEGIN_DATA$/,/^END_DATA$/{
             s="";
             if (NF<2) next; else 
                for (j in a)
            s=s?s"\t"$j:$j
            print s 
            }
48.34   -55.88  19.19   (Untitled 0)
26.95   24.36   13.43   (Untitled 1)
25.53   4.45    -20.68  (Untitled 2)
71.27   6.68    24.28   (Untitled 3)
...
我尝试组合脚本,但没有得到我想要的输出

#!/usr/bin/awk -f

{ sub(/\r$/,"") }

/^BEGIN_DATA_FORMAT/{
        getline
            for (i=1;i<=NF;i++) 
                    if ($i~/LAB/) a[i]=$i
                }


/^BEGIN_DATA$/,/^END_DATA$/{
             s="";
             if (NF<2) next; else 
                for (j in a)
            s=s?s"\t"$j:$j
            print s 
                        }

    { 
        OFS = "\t"
        $4="(Untitled "FNR-1")"
        print $4 
    }
我也试过:

#!/usr/bin/awk -f

{ sub(/\r$/,"") }

/^BEGIN_DATA_FORMAT/{
        getline
            for (i=1;i<=NF;i++) 
                    if ($i~/LAB/) a[i]=$i
                }


/^BEGIN_DATA$/,/^END_DATA$/{
             s="";
             if (NF<2) next; else 
                for (j in a)
            s=s?s"\t"$j:$j

        OFS = "\t"
        $4="(Untitled "FNR-1")"
        print s OFS $4 
            }

有人能告诉我组合这些脚本的正确方法吗?

只需使用递增变量而不是记录编号:

print s, "(Untitled " count++ ")"
您应该在
BEGIN
块中定义
OFS
,而不是为每一行重新定义它


与其执行
{sub(/\r$/,“”)}
不如先在文件上使用“dos2unix”?

第一个脚本仅在满足
/^BEGIN\u DATA$/,/^END\u DATA$/
时打印

当满足上述条件时,组合脚本将执行其
打印s
,并对每行执行
打印$4
,无论是否满足该条件

正如glenn jackman所指出的,问题在于FNR是“记录数”。当从一个脚本传输到另一个脚本时,第二个脚本只获取第一个脚本的输出,因此每个输出行都是第二个脚本的新记录

您需要一个不同于FNR的计数器

BEGIN {
  count=0;
}

...

/^BEGIN_DATA$/,/^END_DATA$/ {
  s="";
  if (NF<2) {
    next;
  } else {
    for (j in a) [
            s=s?s"\t"$j:$j;
    }
    printf("%s\t(Untitled %d)", s, count++);
  }
}
开始{
计数=0;
}
...
/^开始_DATA$/,/^END _DATA$/{
s=“”;

如果这是另一个管道。如果可以,最好减少工具的数量,不是吗?我经常留下“grep”通过在awk中添加一个额外的条件来摆脱一系列管道。这也没什么不同。@glenn jackman谢谢,我第一次听说awk是在两周前。我认为增加一个变量太清楚了,因为我被困在了一个特定的路径上。我也没有使用dos2unix使运行这个脚本成为真正需要的唯一步骤。这是非常重要的不一定要初始化变量:awk会将未定义的变量视为零(在数字上下文中)或空字符串。我知道,但为了清楚起见,我通常会初始化它们。
BEGIN {
  count=0;
}

...

/^BEGIN_DATA$/,/^END_DATA$/ {
  s="";
  if (NF<2) {
    next;
  } else {
    for (j in a) [
            s=s?s"\t"$j:$j;
    }
    printf("%s\t(Untitled %d)", s, count++);
  }
}