Reputation: 4718
I have a script that when I finally pipe to
awk -F'[()]' '{
printf("%s %s\n", $2, $4)
}'
returns
251.393GB 103.005GB
245.296GB 101.992GB
250.526GB 103.639GB
259.158GB 112.549GB
245.266GB 102.415GB
325.020GB 129.041GB
245.135GB 102.086GB
250.583GB 103.758GB
244.247GB 103.268GB
251.256GB 104.008GB
244.496GB 102.643GB
265.133GB 113.523GB
250.332GB 103.556GB
319.579GB 127.401GB
250.140GB 103.722GB
244.765GB 102.541GB
However, I would like to convert GB
(which I have found acts as 1024^3) to MB
(which I would like to express as 1000^2).
Using awk
, how can I detect the unit (GB
, MB
, etc.) and convert it to the appropriate related unit using 1000 instead of 1024? In essence I would like to simply treat GB
as *(1024*1024*1024)/(1000*1000)
Upvotes: 0
Views: 982
Reputation: 37298
How about
echo "319.579GB 127.401GB" \
| awk '{sub(/GB$/,"",$1);sub(/GB$/,"",$2);printf("%.3f\t%.3f\n", $1*(1024*1024*1024)/(1000*1000) , $2*(1024*1024*1024)/(1000*1000))}'
output
43145.338 136795.782
The same for a file
awk '{sub(/GB$/,"",$1);sub(/GB$/,"",$2)
printf("%.3f\t%.3f\n", $1*(1024*1024*1024)/(1000*1000) , $2*(1024*1024*1024)/(1000*1000))}' file
You can adjust the decimal precision but changing the .3
value, or leave it off altogehter if you just want an integer value.
sub(...)
works by matching GB
at the end of the line $
, and replaces with empty string (""
) for the named column (i.e. $1
or $2
). sub
will accept any string value in the 3rd field, so "strGB", arr[1]
, arr[key]` and others will work also.
Upvotes: 0
Reputation: 4340
first, precalculate the multiplier:
awk 'BEGIN{print (1024*1024*1024)/(1000*1000)}'
1073.74
then find fields with "GB", multiply them, and append "MB".
awk '{
if($1~"GB") $1=1073.74*$1"MB"
if($2~"GB") $2=1073.74*$2"MB"
print $1, $2
}'
(both GNU awk
and awk
handle math on strings by only considering the number characters, e.g., "123.45GB" * 10
yields 1234.5
)
Upvotes: 0
Reputation: 204035
$ cat file
251.393GB 103.005GB
245.296GB 101.992GB
250.526GB 103.639GB
$ awk '{for (i=1;i<=NF;i++) printf "%sMB%s", $i * ($i~/GB/ ? 1073.4 : 1), (i<NF ? OFS : ORS)}' file
269845MB 110566MB
263301MB 109478MB
268915MB 111246MB
or if you prefer:
$ awk '{for (i=1;i<=NF;i++) printf "%.3fMB%s", $i * ($i~/GB/ ? 1073.4 : 1), (i<NF ? OFS : ORS)}' file
269845.246MB 110565.567MB
263300.726MB 109478.213MB
268914.608MB 111246.103MB
Upvotes: 2
Reputation: 23677
Solution using perl
where the e
flag comes handy in such cases
$ cat ip.txt
251.393GB 103.005GB
245.296GB 101.992GB
250.526GB 103.639GB
Without limiting decimal precision
$ perl -pe 's|([0-9.]+)GB|$1*(1024*1024*1024)/(1000*1000)|ge' ip.txt
269931.178360832 110600.77658112
263384.574459904 109513.076113408
269000.244199424 111281.528897536
With precision
$ perl -pe 's|([0-9.]+)GB|sprintf "%.3f",$1*(1024*1024*1024)/(1000*1000)|ge' ip.txt
269931.178 110600.777
263384.574 109513.076
269000.244 111281.529
Pre-calculating factor
$ perl -pe 'BEGIN{$m=(1024*1024*1024)/(1000*1000)} s|([0-9.]+)GB|sprintf "%.3f",$1*$m|ge' ip.txt
269931.178 110600.777
263384.574 109513.076
269000.244 111281.529
To print MB
in output as well, use %.3fMB
Upvotes: 1