2016-05-19 13 views
1
in einem Datensatz ist

Ich habe meine vmstat Ausgabe auf einer Linux-Box als solche:

# 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 

Ich beabsichtige, den Wert unter jedem Feld in einem kommagetrennten Format zusammen mit Zeitstempel zu halten (natürlich, um es als CSV-Datei zu verwenden, um später in unser sehr liebevolles MS Excel übertragen zu werden). Also im Grunde ist es das, was ich will:

Erwartete Ausgabe:

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;}}' 

Ausgabe, die ich von meinem Skript erhalten:

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

Beachten Sie die zusätzlichen Platz : 58 ,1 und die letzte 0 fehlt bei der erwarteten Ausgabe. Ich weiß, dass der Teil in meinem Skript, der versaut ist, ist: rec=rec","$i

Wie umgehe ich das?

+2

'while (i <= NF)' sollte die fehlende 0 am Ende beheben. – ReluctantBIOSGuy

Antwort

3

keine Notwendigkeit awk Funktionen

$ 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 
1

i < = NF neu zu erfinden Pflege des fehlenden nehmen nachlauf 0.

Statt über die Felder von Looping, eine awk'ish Weise die tun Dasselbe gilt für OFS - Output Field Separator auf ",".

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

Eine kleine Panne mit diesem ist, dass awk umformatieren nicht $ 0 bis etwas geändert wird. $ 1 = $ 1 Einstellung ist genug awk zu zwingen, das zu tun, (setting the output field separator in awk)

2

Der zusätzliche Platz in 58 ,1 ist, weil Sie awk doch sagen, einen Raum (OFS) zwischen dt drucken (die in 58 endet) und rec (die beginnt mit ,1) mit dem Komma in print dt,rec, nichts mit rec=rec","$i zu tun.

Das fehlende letzte Feld ist, weil Sie awk sagen, die Schleife vor dem letzten Feld zu stoppen. Das Ändern von while (i < NF) zu while (i <= NF) hätte das behoben, aber die Schleife ist überhaupt nicht notwendig (siehe unten).

Ich nehme an, Sie haben keine GNU awk oder Sie würden strftime() statt date verwenden.

Haben nicht shell Anruf awkshell rufen date zu rufen und dann ein pipe zu getline (btw unsafely, die Sie verwenden, http://awk.freeshell.org/AllAboutGetline sehen):

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

haben gerade shell Anruf date:

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

und nach dem Entfernen der UUOC ist das vollständige Skript einfach:

$ 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