如何在END之前检测awk中的最后一行?

时间:2014-10-15 08:19:36

标签: awk concatenation

我正在尝试连接字符串值并打印它们,但如果最后的类型是字符串并且没有类型更改,那么连接将不会打印:

input.txt中:

String 1
String 2
Number 5
Number 2
String 3
String 3

AWK:

awk '

BEGIN { tot=0; ant_t=""; }

{ 
  t = $1; val=$2;
  #if string, concatenate its value
  if (t == "String") {
    tot+=val;
    nx=1;
  } else {
    nx=0; 
  }
  #if type change, add tot to res
  if (t != "String" && ant_t == "String") {
    res=res tot;
    tot=0;
  }
  ant_t=t;
  #if string, go next
  if (nx == 1) {
    next;
  }
  res=res"\n"val;
}

END { print res; }' input.txt

当前输出:

3
5
2

预期产出:

3
5
2
6

如何检测awk是否正在读取最后一行,所以如果不改变类型,它将检查它是否是最后一行?

4 个答案:

答案 0 :(得分:2)

喜欢这样:

awk -v lines="$(wc -l < /etc/hosts)" 'NR==lines{print "LAST"};1' /etc/hosts

我正在预先计算行数(使用wc)并将其作为名为awk的变量传递给lines,如果不清楚的话。

答案 1 :(得分:2)

awk逐行读取,因此无法确定它是否正在读取最后一行。一旦文件结束到达,END块可用于执行操作。

执行您的期望

awk '/String/{sum+=$2} /Number/{if(sum) print sum; sum=0; print $2} END{if(sum) print sum}'

将产生输出

3
5
2
6

它的作用是什么?

/String/选择与String匹配的行,因此Number

sum+=$2执行与String行的连接。发生Number时,请打印sum并重置为零

答案 2 :(得分:1)

awk '$1~"String"{x+=$2;y=1}$1~"Number"{if (y){print x;x=0;y=0;}print $2}END{if(y) print x}' file

<强>解释

  • y用作boolean,如果最后一个模式是END,我会检查string并打印总和
  • 您实际上可以使用x作为类似nu11p01n73R的布尔值更聪明

<强>测试

$ cat file
String 1
String 2
Number 5
Number 2
String 3
String 3
$ awk '$1~"String"{x+=$2;y=1}$1~"Number"{if (y){print x;x=0;y=0;}print $2}END{if(y) print x}' file
3
5
2
6

答案 3 :(得分:1)

只需将最后一行更改为:

END { print res; print tot;}'