[英]In AWK `rec=rec“,”$i` doesn't work as expected, where $i is each field in a record
I've my vmstat
output on a linux box as such: 我将
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
I intend to keep the value under each field in a comma separated format along with timestamp(of course to use it as CSV file to be later transferred to our very loving MS Excel). 我打算将每个字段下的值与时间戳一起保留在逗号分隔的格式中(当然,将其用作CSV文件,以后再传输到我们非常喜欢的MS Excel中)。 So basically this is what I want:
所以基本上这就是我想要的:
Expected Output: 预期产量:
2016,05,19,23,53,58,1,0,0,2675664,653028,3489156,0,0,1,19,22,7,5,1,94,0,0
Script: 脚本:
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;}}'
Output that I get from my script: 我从脚本获得的输出:
2016,05,19,23,53,58 ,1,0,0,2675664,653028,3489156,0,0,1,19,22,7,5,1,94,0
Note the extra space : 58 ,1
and the last 0
missing from Expected Output. 请注意额外的空间:
58 ,1
和预期输出中缺少最后一个0
。 I know the part in my script that is messing up is: rec=rec","$i
我知道脚本中混乱的部分是:
rec=rec","$i
How to get around this ? 如何解决这个问题?
no need to reinvent awk
features 无需重新设计
awk
功能
$ awk -v OFS=, 'BEGIN{time=strftime("%Y,%m,%d,%H,%M,%S")}
NR>2{$1=$1; print time,$0}' file
2016,05,19,15,12,29,1,0,0,2675664,653028,3489156,0,0,1,19,22,7,5,1,94,0,0
The extra space in 58 ,1
is because you're telling awk to print a space (OFS) between dt (which ends in 58
) and rec (which starts with ,1
) with the comma in print dt,rec
, nothing to do with rec=rec","$i
. 在额外的空间
58 ,1
是因为你告诉AWK打印空间(OFS)DT之间(在此结束58
)和REC(其中开头,1
用逗号) print dt,rec
,无关使用rec=rec","$i
。
The missing last field is because you're telling awk to stop looping before the last field. 缺少最后一个字段是因为您要告诉awk在最后一个字段之前停止循环。 Changing
while (i < NF)
to while (i <= NF)
would have fixed that but the loop's not necessary at all (see below). 将
while (i < NF)
更改为while (i <= NF)
可以解决此问题,但根本不需要循环(请参见下文)。
I'm assuming you don't have GNU awk or you'd be using strftime()
instead of date
. 我假设您没有GNU awk,或者您将使用
strftime()
代替date
。
Don't have shell
call awk
to call shell
to call date
and then a pipe
to getline
(which you're using unsafely btw, see http://awk.freeshell.org/AllAboutGetline ): 不要让
shell
调用awk
来调用shell
来调用date
,然后再使用pipe
来获取getline
(您正在不安全地使用btw,请参阅http://awk.freeshell.org/AllAboutGetline ):
awk 'BEGIN{"date +'%Y,%m,%d,%H,%M,%S'"| getline dt;} {script}'
Just have shell
call date
: 只需具有
shell
调用date
:
awk -v dt=$(date +'%Y,%m,%d,%H,%M,%S') '{script}'
and after getting rid of the UUOC the full script is simply: 摆脱了UUOC之后,完整的脚本就是:
$ awk -v dt=$(date +'%Y,%m,%d,%H,%M,%S') -v OFS=, 'NR>2{$1=dt OFS $1; 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
i <= NF will take care of the missing trailing 0. i <= NF将处理丢失的尾随0。
Instead of looping over the fields, a more awk'ish way of doing the same thing is to set OFS - Output Field Separator to ",". 而不是遍历这些字段,执行相同操作的一种更奇怪的方法是将OFS-输出字段分隔符设置为“,”。
awk ' BEGIN{OFS="," ; "date +'%Y,%m,%d,%H,%M,%S'"| getline dt;} {if (NR> 2) {$1=$1 ; print dt,$0;}} ' vmstat.out
One small glitch with that is that awk doesn't reformat $0 until something is changed. 其中的一个小故障是awk在更改某些内容之前不会重新格式化$ 0。 Setting $1=$1 is enough to force awk to do that ( setting the output field separator in awk )
设置$ 1 = $ 1足以迫使awk做到这一点( 在awk中设置输出字段分隔符 )
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.