I've my vmstat
output on a linux box as such:
# 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). 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. I know the part in my script that is messing up is: rec=rec","$i
How to get around this ?
no need to reinvent awk
features
$ 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
.
The missing last field is because you're telling awk to stop looping before the last field. Changing while (i < NF)
to while (i <= NF)
would have fixed that but the loop's not necessary at all (see below).
I'm assuming you don't have GNU awk or you'd be using strftime()
instead of 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 ):
awk 'BEGIN{"date +'%Y,%m,%d,%H,%M,%S'"| getline dt;} {script}'
Just have shell
call date
:
awk -v dt=$(date +'%Y,%m,%d,%H,%M,%S') '{script}'
and after getting rid of the UUOC the full script is simply:
$ 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.
Instead of looping over the fields, a more awk'ish way of doing the same thing is to set OFS - Output Field Separator to ",".
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. Setting $1=$1 is enough to force awk to do that ( setting the output field separator in awk )
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.