问题
I have a requirement as below
121.36
121.025
121.1
121.000
Desired output
122
122
122
121
Command used
awk -F"." '{if($8>0){print $11}}'
回答1:
What you're asking for is a ceil()
(for "ceiling") function. It's important to include zero and negative numbers in your example when you're looking for any kind of rounding function as it's easy to get them wrong so using this input file:
$ cat file
1.999999
1.0
0.000001
0
-0.000001
-1.0
-1.999999
we can test a ceil()
function:
$ awk 'function ceil(x, y){y=int(x); return(x>y?y+1:y)} {print $0,ceil($0)}' file
1.999999 2
1.0 1
0.000001 1
0 0
-0.000001 0
-1.0 -1
-1.999999 -1
and the opposite floor()
function:
$ awk 'function floor(x, y){y=int(x); return(x<y?y-1:y)} {print $0,floor($0)}' file
1.999999 1
1.0 1
0.000001 0
0 0
-0.000001 -1
-1.0 -1
-1.999999 -2
The above works because int()
truncates towards zero (from the GNU awk manual):
int(x)
Return the nearest integer to x, located between x and zero and
truncated toward zero. For example, int(3) is 3, int(3.9) is 3,
int(-3.9) is -3, and int(-3) is -3 as well.
so int()
of a negative number already does what you want for a ceiling function, i.e. round up, and you just have to add 1 to the result if int()
rounded down a positive number.
I used 0.000001
, etc. in the samples to avoid people getting a false positive testing a solution that adds some number like 0.9
and then int()
ing.
Also note that ceil()
could be abbreviated to:
function ceil(x){return int(x)+(x>int(x))}
but I wrote it as above for clarity (it's not clear/obvious that the result of x>int(x)
is 1 or 0) and efficiency (only call int()
once instead of twice).
回答2:
I was trying to find a way to do this in plain bash, but since bash can only do integer arithmetic I failed. You do need another language to work with you here.
I would write a shell function as a wrapper around that other langugage. For example:
$ ceil() { perl -MPOSIX=ceil -lpe '$_ = ceil($_)'; }
$ ceil <<END
121.36
121.025
121.1
121.000
0.1
0
-0.1
-3.0
-3.1
END
outputs
122
122
122
121
1
0
0
-3
-3
Any other language will do: ceil() { ruby -ne 'puts $_.to_f.ceil'; }
来源:https://stackoverflow.com/questions/37432680/roundup-function-in-unix