4

How can I convert bytes to gigabytes in each line in single column in Bash? I have tried this:

echo "scale=2; $(cat file.log) / 1024^2" | bc 

but that convert only last value.

Example of file.log content:

 2171863040 1693491200 1984045056 

(without spaces between)

5
  • Can you provide file.log? Commented Jun 20, 2019 at 15:08
  • 3
    Please add sample input and your desired output for that sample input to your question. Commented Jun 20, 2019 at 15:09
  • ... and your desired output Commented Jun 20, 2019 at 15:16
  • Desired output is same column but in GB. Commented Jun 20, 2019 at 15:18
  • 3
    Don't just tell us about it - show the actual output you expect to get from your posted sample input in your question. Commented Jun 20, 2019 at 15:19

3 Answers 3

10

You could use awk:

$ cat file.log 1073741824 1073741824 $ awk '{print $1/1024/1024/1024 " GB " $2/1024/1024/1024 " GB"}' file.log 1 GB 1 GB 

or using the sample data you just posted:

$ awk '{print $1/1024/1024/1024 " GB "}' file.log 2.02271 GB 1.57719 GB 1.84779 GB 
Sign up to request clarification or add additional context in comments.

Comments

8

awk will be cleaner, simpler, and faster -

awk '{ printf "%.2f\n", $1/1024/1024/1024; }' file.log 2.02 1.58 1.85 

bc needs a loop, and doesn't round properly.

$: while read b > do bc <<< "scale=2; $b / 1024^3" # shouldn't GB be ^3? > done < file.log 2.02 1.57 1.84 

You can get the rounding with printf and another layer of subshell...
Drop the scale and use bc -l:

$: while read b; do printf '%.2f\n' $(bc -l<<<"$b/1024^3"); done < file.log 2.02 1.58 1.85 

or some program to format lines of your file into commands for bc in place of the loop, which eliminates a separate call to bc for every line of your file -

$: printf '%.2f\n' $( sed 's,$,/1024^3,' tmp | bc -l ) 2.02 1.58 1.85 

...but I'd just use the awk.

edit --

New upvote made me look at this again. Comment elsewhere is inaccurate, but has a valid point.

I am converting to gibibytes, which are powers of two, rather than gigabytes, which are powers of ten. I assumed that was what was wanted, because of the technically incorrect usage in prevalence.

If OP actually meant they wanted powers of 10 instead of two, just switch the 1024's to 1000's -

awk '{for (i = 1; i <= NF; i++) $i = ($i/(1000*1000*1000)); print }' file.log 

...though I doubt that's what they meant, it is good to be clear, specific, and accurate.

1 Comment

Awesome, thanks for including the examples with limiting the decimal places ;)
3

If you want to recalculate each field (space separated) in a row.

This awk script will do the work.

awk '{for (i = 1; i <= NF; i++) $i = ($i/(1024*1024*1024)); print }' file.log 

1 Comment

You are converting to MiB when OP wants to do GB.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.