Rounding numbers with bash tools
Rounding numbers with bash tools
am 12.09.2007 09:23:09 von Haakon
I'm trying to clean up some textfiles that contain numbers like this:
1.2999934 2.3000124 4.199912 ..and so on.
Basically the numbers have too many digits, so I want to reduce the
amount of digits and do the appropriate rounding where necessary so
that 1.2999934 becomes 1.300.
I know awk can do something like this:
> echo 1.2999934 | awk ' { printf "%.3f\n", $0 } '
1.300
But I don't know how I can script it so that all numbers with say more
than 5 digits are found and replaced with its appropriate rounded 3-
digit equivalent.
Anyone got any tips & tricks?
Re: Rounding numbers with bash tools
am 12.09.2007 09:32:57 von Stephane CHAZELAS
2007-09-12, 00:23(-07), haakon:
> I'm trying to clean up some textfiles that contain numbers like this:
> 1.2999934 2.3000124 4.199912 ..and so on.
> Basically the numbers have too many digits, so I want to reduce the
> amount of digits and do the appropriate rounding where necessary so
> that 1.2999934 becomes 1.300.
>
> I know awk can do something like this:
>> echo 1.2999934 | awk ' { printf "%.3f\n", $0 } '
> 1.300
>
> But I don't know how I can script it so that all numbers with say more
> than 5 digits are found and replaced with its appropriate rounded 3-
> digit equivalent.
[...]
perl -pe 's/\d*\.\d{5,}/sprintf "%.3f", $&/ge'
--
Stéphane
Re: Rounding numbers with bash tools
am 12.09.2007 09:52:24 von Haakon
>
> perl -pe 's/\d*\.\d{5,}/sprintf "%.3f", $&/ge'
>
> --
That works very well :)
Re: Rounding numbers with bash tools
am 12.09.2007 10:13:05 von Haakon
> > perl -pe 's/\d*\.\d{5,}/sprintf "%.3f", $&/ge'
>
> > --
>
Is it possible to give address ranges directly to perl so that say
only the first 100 lines gets affected?
Re: Rounding numbers with bash tools
am 12.09.2007 10:33:16 von Stephane CHAZELAS
2007-09-12, 01:13(-07), haakon:
>> > perl -pe 's/\d*\.\d{5,}/sprintf "%.3f", $&/ge'
>>
>> > --
>>
>
> Is it possible to give address ranges directly to perl so that say
> only the first 100 lines gets affected?
perl -pe 's/\d*\.\d{5,}/sprintf "%.3f", $&/ge if $. <= 100'
--
Stéphane
Re: Rounding numbers with bash tools
am 12.09.2007 10:47:00 von Haakon
>
> perl -pe 's/\d*\.\d{5,}/sprintf "%.3f", $&/ge if $. <= 100'
>
> --
Exactly what I wanted! Cheers.
btw, if anyone has a python- or awk solution to it as well I'd be
interested in seeing them.
Re: Rounding numbers with bash tools
am 12.09.2007 10:47:15 von Haakon
>
> perl -pe 's/\d*\.\d{5,}/sprintf "%.3f", $&/ge if $. <= 100'
>
> --
Exactly what I wanted! Cheers.
btw, if anyone has a python- or awk solution to it as well I'd be
interested in seeing them.
Re: Rounding numbers with bash tools
am 12.09.2007 10:50:51 von Haakon
>
> perl -pe 's/\d*\.\d{5,}/sprintf "%.3f", $&/ge if $. <= 100'
>
> --
Exactly what I wanted! Cheers.
btw, if anyone has a python- or awk solution to it as well I'd be
interested in seeing them.
Re: Rounding numbers with bash tools
am 12.09.2007 12:43:36 von Stephane CHAZELAS
2007-09-12, 01:50(-07), haakon:
>>
>> perl -pe 's/\d*\.\d{5,}/sprintf "%.3f", $&/ge if $. <= 100'
>>
>
> Exactly what I wanted! Cheers.
>
>
> btw, if anyone has a python- or awk solution to it as well I'd be
> interested in seeing them.
[...]
You can do it in awk, but it's a lot more painful. You'd need to
use a combination of match(), RSTART, RLENGTH and substr() in some
loop.
I'm sure someone will come up with a ruby version soon ;),
python is not that well suited for this kind of quick text
processing job.
--
Stéphane
Re: Rounding numbers with bash tools
am 12.09.2007 20:02:47 von Cyrus Kriticos
haakon wrote:
> I'm trying to clean up some textfiles that contain numbers like this:
> 1.2999934 2.3000124 4.199912 ..and so on.
> Basically the numbers have too many digits, so I want to reduce the
> amount of digits and do the appropriate rounding where necessary so
> that 1.2999934 becomes 1.300.
>
> I know awk can do something like this:
>> echo 1.2999934 | awk ' { printf "%.3f\n", $0 } '
> 1.300
shorter:
$ x=1.2999934
$ printf "%.3f\n" $x
1.300
--
Best regards | "The only way to really learn scripting is to write
Cyrus | scripts." -- Advanced Bash-Scripting Guide
Re: Rounding numbers with bash tools
am 12.09.2007 23:12:17 von Haakon
> perl -pe 's/\d*\.\d{5,}/sprintf "%.3f", $&/ge if $. <= 100' $1
Say I want to put the above perl code into a bash-script that I call
from the commandline like this:
round_digits.sh inputfile.txt > outputfile.txt
Is it possible to do a variable substitution with the perl-code so
that the numbers of digits can be specified from the commandline when
invoking the script? Example:
round_digits.sh inputfile.txt 3 > outputfile.txt
I seem to be getting in serious quoting issues if I try something like
replacing "%3.f" with "%$2.f"
Re: Rounding numbers with bash tools
am 13.09.2007 03:51:22 von Dummy
haakon wrote:
>> perl -pe 's/\d*\.\d{5,}/sprintf "%.3f", $&/ge if $. <= 100' $1
>
> Say I want to put the above perl code into a bash-script that I call
> from the commandline like this:
>
> round_digits.sh inputfile.txt > outputfile.txt
>
> Is it possible to do a variable substitution with the perl-code so
> that the numbers of digits can be specified from the commandline when
> invoking the script? Example:
>
> round_digits.sh inputfile.txt 3 > outputfile.txt
>
> I seem to be getting in serious quoting issues if I try something like
> replacing "%3.f" with "%$2.f"
perl -spe's/\d*\.\d{5,}/sprintf "%.*f", $width || 3, $&/ge if $. <= 100' --
-width=3 inputfile.txt > outputfile.txt
John
--
Perl isn't a toolbox, but a small machine shop where you
can special-order certain sorts of tools at low cost and
in short order. -- Larry Wall
Re: Rounding numbers with bash tools
am 13.09.2007 22:39:25 von Haakon
> perl -spe's/\d*\.\d{5,}/sprintf "%.*f", $width || 3, $&/ge if $. <= 100' --
> -width=3 inputfile.txt > outputfile.txt
>
I can't make the above work. I'm new to Perl and not quite familiar
with the syntax yet. I understand that the -s switch allows for the
variable 'width' to be given after the perl program itself. Is this
the correct syntax though? The error message it gives me is:
Name "main::width" used only once: possible typo at -e line 1.
Use of uninitialized value in sprintf at -e line 1, <> line 3.
Use of uninitialized value in sprintf at -e line 1, <> line 3.
Use of uninitialized value in sprintf at -e line 1, <> line 4.
Use of uninitialized value in sprintf at -e line 1, <> line 4.
Use of uninitialized value in sprintf at -e line 1, <> line 5.
...
...
... and so on..
Re: Rounding numbers with bash tools
am 14.09.2007 01:18:54 von Dummy
haakon wrote:
>> perl -spe's/\d*\.\d{5,}/sprintf "%.*f", $width || 3, $&/ge if $. <= 100' --
>> -width=3 inputfile.txt > outputfile.txt
You do realise that that is supposed to be all on one line?
> I can't make the above work. I'm new to Perl and not quite familiar
> with the syntax yet. I understand that the -s switch allows for the
> variable 'width' to be given after the perl program itself. Is this
> the correct syntax though? The error message it gives me is:
>
> Name "main::width" used only once: possible typo at -e line 1.
The only way that you could have gotten this message is if you had used the -w
switch to perl which my example doesn't use.
> Use of uninitialized value in sprintf at -e line 1, <> line 3.
> Use of uninitialized value in sprintf at -e line 1, <> line 3.
> Use of uninitialized value in sprintf at -e line 1, <> line 4.
> Use of uninitialized value in sprintf at -e line 1, <> line 4.
> Use of uninitialized value in sprintf at -e line 1, <> line 5.
The only way that you could have gotten this message is if you had used just
$width as the second argument to sprintf() instead of my example which uses
$width || 3.
John
--
Perl isn't a toolbox, but a small machine shop where you
can special-order certain sorts of tools at low cost and
in short order. -- Larry Wall
Re: Rounding numbers with bash tools
am 14.09.2007 21:52:44 von Haakon
> perl -spe's/\d*\.\d{5,}/sprintf "%.*f", $width || 3, $&/ge if $. <= 100' --
> -width=3 inputfile.txt > outputfile.txt
Got it working, Thanks!!
Is it possible to also substitute the other values in the perl code,
specifically:
- the number of digits in the regex \d{5,}
- the number of lines to be processed.
Re: Rounding numbers with bash tools
am 14.09.2007 22:49:34 von Dummy
haakon wrote:
>> perl -spe's/\d*\.\d{5,}/sprintf "%.*f", $width || 3, $&/ge if $. <= 100' --
>> -width=3 inputfile.txt > outputfile.txt
>
> Got it working, Thanks!!
>
> Is it possible to also substitute the other values in the perl code,
> specifically:
> - the number of digits in the regex \d{5,}
> - the number of lines to be processed.
perl -spe's/\d*\.\d{$digits,}/sprintf "%.*f", $width || 3, $&/oge if $. <=
$lines' -- -width=3 -digits=5 -lines=100 inputfile.txt > outputfile.txt
John
--
Perl isn't a toolbox, but a small machine shop where you
can special-order certain sorts of tools at low cost and
in short order. -- Larry Wall