Home > database >  Have equal space in awk printf
Have equal space in awk printf

Time:05-10

I have a csv file with following content.

"TELUS","Vancouver Canada","67.151","0.325","0","63247942","64210661","768241424","858087937"
"TELUS","Vancouver Canada","7.151","0.325","0","63247942","64210661","768241424","858087937"

With the help of awk, I have successfully parsing them to readable format.

awk -F, '{gsub(/"/, ""); printf "| %-11s | %-17s | %.1f %-6s | %.1f %-6s | %.1f %-6s | %.1f %-5.16s |\n", $1, $2, $7/125000, "MB/s", $6/125000, "MB/s", ($8 $9)/(1000*1000*1000), "GB", $3, "ms" }'

Return this

| TELUS       | Vancouver Canada  | 513.7 MB/s   | 506.0 MB/s   | 1.6 GB     | 67.2 ms    |
| TELUS       | Vancouver Canada  | 513.7 MB/s   | 506.0 MB/s   | 1.6 GB     | 7.2 ms    |

But as you can see the space is not equal on latency field. I want it to be like this.

| TELUS       | Vancouver Canada  | 513.7 MB/s   | 506.0 MB/s   | 1.6 GB     | 67.2 ms   |
| TELUS       | Vancouver Canada  | 513.7 MB/s   | 506.0 MB/s   | 1.6 GB     | 7.2 ms    |
| TELUS       | Vancouver Canada  | 513.7 MB/s   | 506.0 MB/s   | 1.6 GB     | 947.2 ms  |
| TELUS       | Vancouver Canada  | 513.7 MB/s   | 506.0 MB/s   | 1.6 GB     | 7241.2 ms |

I'm putting two extra field at above, the point is I want to keep the column spacing intact no matter how large the latency is. How to do this?

CodePudding user response:

try { %9.3f %-3.16s }:

echo "${a}" | mawk  '{ gsub(/[\42]/,"")

    printf "| %-11s | %-17s | %.1f %-6s | %.1f %-6s  "\
           "| %.1f %-6s | %9.3f %-3.16s |\n",\
                $1        ,     $2,
                $7 * 8E-6 , "MB/s",\
                $6 * 8E-6 , "MB/s", \
            ($8 $9)*(1E-9), "GB"  , $3, "ms" }' FS=','

| TELUS       | Vancouver Canada  | 513.7 MB/s   | 506.0 MB/s    | 1.6 GB     |    67.151 ms  |
| TELUS       | Vancouver Canada  | 513.7 MB/s   | 506.0 MB/s    | 1.6 GB     |     7.151 ms  |

CodePudding user response:

You may use this awk solution:

cat fmt.awk
{
   gsub(/"/, "")
   printf ("| %-11s | %-17s | %.1f %-6s | %.1f %-6s | %.1f %-6s | s |\n",
      $1, $2, $7/125000, "MB/s", $6/125000, "MB/s", ($8 $9)/(1000*1000*1000),
      "GB", sprintf("%.1f ms", $3))
}

awk -F, -f fmt.awk file.csv

| TELUS       | Vancouver Canada  | 513.7 MB/s   | 506.0 MB/s   | 1.6 GB     |    67.2 ms |
| TELUS       | Vancouver Canada  | 513.7 MB/s   | 506.0 MB/s   | 1.6 GB     |     7.2 ms |

Used sprintf("%.1f ms", $3) to get single digit decimal point inn $3 followed by ms. This is formatted in main printf with s formatting to get right aligned output with width=10.

CodePudding user response:

Rather than hard-coding field widths, just use awk to calculate the values and column to calculate the widths:

$ awk 'BEGIN{FS=OFS=","} {gsub(/"/, ""); printf ",%s,%s,%.1f MB/s,%.1f MB/s,%.1f GB,%.1f ms, \n", $1, $2, $7/125000, $6/125000, ($8 $9)/(1000*1000*1000), $3}' file |
    column -t -s',' -o' | ' | sed 's/^ //; s/ $//'
| TELUS | Vancouver Canada | 513.7 MB/s | 506.0 MB/s | 1.6 GB | 67.2 ms |
| TELUS | Vancouver Canada | 513.7 MB/s | 506.0 MB/s | 1.6 GB | 7.2 ms  |

but if you want to do the formatting in awk then again separate the field widths (e.g. %-17s) from the field contents (e.g. rounding to %.1f):

$ awk -F, -v CONVFMT='%.1f' '{gsub(/"/, ""); printf "| %-11s | %-17s | %-10s | %-10s | %-10s | %-10s |\n", $1, $2, $7/125000 " MB/s", $6/125000 " MB/s", ($8 $9)/(1000*1000*1000) " GB", $3 " ms" }' file
| TELUS       | Vancouver Canada  | 513.7 MB/s | 506.0 MB/s | 1.6 GB     | 67.151 ms  |
| TELUS       | Vancouver Canada  | 513.7 MB/s | 506.0 MB/s | 1.6 GB     | 7.151 ms   |
  • Related