AWK打印FNR从0开始递增

时间:2012-01-31 23:29:49

标签: 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="";
             if (NF<2) next; else 
                for (j in a)
            s=s?s"\t"$j:$j
            print s 
            }

这是此脚本的输出结果:

48.34   -55.88  19.19
26.95   24.36   13.43
25.53   4.45    -20.68
71.27   6.68    24.28
...

这是我的第二个剧本:

#!/usr/bin/awk -f

{ OFS = "\t"; $4="(Untitled "FNR-1")"; print $0 }

将第一个脚本输入第二个脚本会返回预期结果,其中FNR从第四个字段的0开始。

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 
    }

这是给出的输出。问题是它引用的是同一个文件而不是最后一个命令的输出。

(Untitled 0)
(Untitled 1)
(Untitled 2)
(Untitled 3)
(Untitled 4)
(Untitled 5)
(Untitled 6)
(Untitled 7)
(Untitled 8)
(Untitled 9)
(Untitled 10)
(Untitled 11)
(Untitled 13)
(Untitled 14)
(Untitled 15)
48.34   -55.88  19.19
(Untitled 17)
26.95   24.36   13.43
(Untitled 18)
25.53   4.45    -20.68
(Untitled 19)
71.27   6.68    24.28
(Untitled 20)
...

我也试过这个:

#!/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 
            }

输出更接近但问题是它仍然从该参数的FNR算起。我需要它从0开始。

48.34   -55.88  19.19   (Untitled 17)
26.95   24.36   13.43   (Untitled 18)
25.53   4.45    -20.68  (Untitled 19)
71.27   6.68    24.28   (Untitled 20)
...

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

2 个答案:

答案 0 :(得分:2)

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

print s, "(Untitled " count++ ")"

您应该在OFS块中定义BEGIN,而不是为每一行重新定义它。

而不是做{ sub(/\r$/,"") }为什么不首先在你的文件上使用“dos2unix”?

答案 1 :(得分:1)

您的第一个脚本仅在满足/^BEGIN_DATA$/,/^END_DATA$/时打印。

当满足上述条件时,您的组合脚本会执行print s,并且无论条件是否满足,每行的print $4都会执行。

正如格伦杰克曼所说,问题在于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++);
  }
}