在 AWK `rec=rec","$i` 中没有按预期工作,其中 $i 是记录中的每个字段

In AWK `rec=rec","$i` doesn't work as expected, where $i is each field in a record

我的 vmstat 输出在 linux 框上,如下所示:

# cat vmstat.out
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 1  0      0 2675664 653028 3489156    0    0     1    19   22    7  5  1 94  0  0

我打算以逗号分隔的格式保留每个字段下的值以及时间戳(当然是将其用作 CSV 文件,以便稍后传输到我们非常喜欢的 MS Excel)。所以基本上这就是我想要的:

预期输出:

2016,05,19,23,53,58,1,0,0,2675664,653028,3489156,0,0,1,19,22,7,5,1,94,0,0

脚本:

cat vmstat.out | awk 'BEGIN{"date +'%Y,%m,%d,%H,%M,%S'"| getline dt;}{if (NR> 2) {i=1;while (i < NF) {rec=rec","$i; i++;} print dt,rec;}}'

我从我的脚本中得到的输出:

2016,05,19,23,53,58 ,1,0,0,2675664,653028,3489156,0,0,1,19,22,7,5,1,94,0

请注意预期输出中缺少的额外 space : 58 ,1 和最后一个 0。我知道我的脚本中出现问题的部分是:rec=rec","$i

如何解决这个问题?

无需重新发明 awk 功能

$ awk -v OFS=, 'BEGIN{time=strftime("%Y,%m,%d,%H,%M,%S")} 
                 NR>2{=; print time,[=10=]}' file

2016,05,19,15,12,29,1,0,0,2675664,653028,3489156,0,0,1,19,22,7,5,1,94,0,0

i <= NF 将处理丢失的尾随 0。

不是在字段上循环,做同样事情的一种更奇怪的方法是将 OFS - 输出字段分隔符设置为“,”。

awk ' BEGIN{OFS="," ; "date +'%Y,%m,%d,%H,%M,%S'"| getline dt;} {if (NR> 2) {= ; print dt,[=10=];}} ' vmstat.out

其中的一个小故障是 awk 在更改内容之前不会重新格式化 $0。设置 $1=$1 足以强制 awk 这样做 (setting the output field separator in awk)

58 ,1 中额外的 space 是因为你告诉 awk 在 dt(以 58 结尾)和 rec 之间打印一个 space (OFS) (以 ,1 开头)与 print dt,rec 中的逗号,与 rec=rec","$i.

无关

缺少最后一个字段是因为您告诉 awk 在最后一个字段之前停止循环。将 while (i < NF) 更改为 while (i <= NF) 会解决这个问题,但根本不需要循环(见下文)。

我假设您没有 GNU awk,或者您将使用 strftime() 而不是 date

没有shell调用awk调用shell调用date然后pipe调用getline(这顺便说一句,你使用的不安全,请参阅 http://awk.freeshell.org/AllAboutGetline):

awk 'BEGIN{"date +'%Y,%m,%d,%H,%M,%S'"| getline dt;} {script}'

只需 shell 调用 date:

awk -v dt=$(date +'%Y,%m,%d,%H,%M,%S') '{script}'

在去掉 UUOC 之后,完整的脚本就是:

$ awk -v dt=$(date +'%Y,%m,%d,%H,%M,%S') -v OFS=, 'NR>2{=dt OFS ; print}' vmstat.out
2016,05,19,14,53,05,1,0,0,2675664,653028,3489156,0,0,1,19,22,7,5,1,94,0,0