POSIX defined length in awk
is a string function, argument taken as a string. Using length
with an array as argument is unspecified behavior.
In some implementations of awk
like gawk (version >= 3.1.6), OS X version of AWK, you can use length
with an array as argument, it will return number of elements in array.
Array in awk
is associative array, looping through associative array does not guarantee anything about the order. In this case, you can take advantage of split function, which return number of fields to get the number elements of array.
POSIXly, you can try:
$ awk -vA="$tstArr2" '
BEGIN{n = split(A,B," ");}
{
if(NR > 1) {
for(i = 1;i <= n;i++) {
printf "%s ",$B[i];
}
}
print " ";
}
' file
SA AUS BRA
INDIA NZ WI
You have the fields in the right order, but your first print statement adds a newline (Output Record Separator), so your data's there, but just wrapped unexpectedly.
The second issue is that you're telling printf to use a width of 4; that includes the decimal point and the two digits after it, leaving only one for the leading digit and none for any padding. Try using 5 as the width, so that your data is padded up to four total numbers. If you want 4 digits before the decimal point, then change the width to 7 instead.
This is the shortest change I made from your program to something that outputs what I think you want:
awk -F"|" '{
format = "%05.2f,%05.2f,%05.2f";
print $1","$2","$3","$4"," sprintf(format, $5,$6,$7)}' filename
I combined multiple { }
blocks into one, and also combined the print statements into one.
If I was to write your awk statement from scratch, I might do something like this:
awk -v FS=\| -v OFS=, '{
$5=sprintf("%05.2f", $5);
$6=sprintf("%05.2f", $6);
$7=sprintf("%05.2f", $7);
print $1,$2,$3,$4,$5,$6,$7}' filename
It explicitly sets the input Field Separator, the Output Field Separator, explicitly converts each of the fields on its own, then prints the desired fields, with the OFS separating them.
Best Answer
You can use
sprintf
to print the new value to a formatted string, and assign that as the new value of$2
:Then it's just a matter of printing the whole (modified) record: