1

I am having a file with numbers in MB units and I wanted to make them in GB then I found a very interesting perl to do this

perl -pe 's{(?<!\d)(\d+(?:\.\d+)?)(?!\d)}{$1/1024}ge'

But I still need to round the results 2 digits after the dot

Currently, results like 260.676914215088

I tried some other Unix tools like cut and bc but it would be better if done within Perl.

BTW the file contains numbers and strings and the above Perl is working as expected but I still need to round results.

I would appreciate if someone helped with the above perl statement as I am already using it to change between different units

user2141046
  • 862
  • 2
  • 7
  • 21
mshafey
  • 89
  • 1
  • 9
  • 1
    Would this answer your question? https://stackoverflow.com/questions/35043874/how-can-i-format-a-number-to-2-decimal-places-in-perl – Lee Goddard Mar 18 '21 at 09:46
  • this didn't answer my question I would appreciate if someone helped with the above perl statement as I am already using it to change between different units – mshafey Mar 18 '21 at 09:55
  • sprintf is not an option on my os – mshafey Mar 18 '21 at 09:56
  • What operating system is that? Please give us all the information or we can't help you. `sprintf` is a core Perl built-in, that's about as system-agnostic as it gets. I've undone the duplicate close now. – simbabque Mar 18 '21 at 10:12
  • I thought I should send results to sprintf command! it seems as you mentioned sprintf is a Perl built-in function but I still won't be able to use it with the above Perl line, a little help would be appreciated, it's aix – mshafey Mar 18 '21 at 10:27
  • 1
    @simbabque I believe his issue is not perl, but integrating the printf into his oneliner – user2141046 Mar 18 '21 at 10:27
  • @user2141046 correct – mshafey Mar 18 '21 at 10:28
  • BTW, I found it here https://stackoverflow.com/questions/56595074/find-and-divide-all-numbers-in-a-file-using-sed and left a comment there but not sure if they can update a new answer for the old question – mshafey Mar 18 '21 at 10:28
  • https://www.perlmonks.org/?node_id=642337 has some interesting examples, including a pointer to Number::Format::Human – brian d foy Mar 18 '21 at 18:27

2 Answers2

3

You can embed the sprintf call into your substitution. You already have the /e modifier, so you can run that command in the substitution part and pass it the calculation you're doing.

#                                         VVVVVVVVVVVVVVVV        V 
perl -pe 's{(?<!\d)(\d+(?:\.\d+)?)(?!\d)}{sprintf("%.02f", $1/1024)}ge'

See it in action here:

$ echo "1234567" | perl -pe 's{(?<!\d)(\d+(?:\.\d+)?)(?!\d)}{sprintf("%.02f", $1/1024)}ge'  
1205.63
simbabque
  • 53,749
  • 8
  • 73
  • 136
0

Since you're dealing with a one-liner, there's no limit to the number of pipes you can give it, so just add this to your line: perl -n -e 'printf ("%.2f\n",$_)'

meaning
perl -pe 's{(?<!\d)(\d+(?:\.\d+)?)(?!\d)}{$1/1024}ge'| perl -n -e 'printf ("%.2f\n",$_)'

e.g.

> echo "12014.324\n10123123.1\n20123.5555" | perl -pe 's{(?<!\d)(\d+(?:\.\d+)?)(?!\d)}{$1/1024}ge' | perl -n -e 'printf ("%.2f\n", $_)'
11.73
9885.86
19.65
user2141046
  • 862
  • 2
  • 7
  • 21