2012-01-31 75 views
1

这是我试图添加最后一个参数的脚本,将FNR打印到第四个字段中。AWK打印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 
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

只需使用一个递增的变量,而不是备案号:

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

你应该在BEGIN块定义,而不是将其重新定义为每一行OFS

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

+0

这是另一个管道。如果可以,最好减少工具的数量,不是吗?我通常会在awk中添加一个额外的条件,从而在一串管道中留下“grep”。这也不例外。 – ghoti 2012-02-01 02:54:03

+0

@glenn jackman谢谢,我有史以来第一次听说AWK。我认为增加一个变量太清楚了,因为我被困在一个特定的路径上。我也没有使用dos2unix来运行这个脚本真的是唯一需要的步骤。 – jeffrbauer 2012-02-01 03:08:22

1

只有当/^BEGIN_DATA$/,/^END_DATA$/符合时,才会打印您的第一个脚本。

当满足上述条件时,您的组合脚本执行它的print s,并且对于每一行都执行print $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++); 
    } 
} 
+1

初始化变量不是必须的:awk会将未定义的变量视为零(在数字上下文中)或空字符串。 – 2012-02-01 11:47:57

+0

我知道,但为了清晰起见,我通常会初始化它们。 – ghoti 2012-02-01 13:23:58