分隔十进制数的整数和小数部分
Separating integer and fractional part of a decimal number
我想分隔一个数字十进制数,将整数部分存储在 bash 变量 ts
中,将小数部分存储在变量 fr
.
中
进行了参数扩展,但继续获取原始数字。
t=13.491675
ts=${t#![0-9]*}
fr=${t%*![0-9]}
这应该适用于任何 decimal separator:
shopt -s extglob
t=13.491675
ts="${t%%[^0-9]+([0-9])}"
fr="${t##+([0-9])[^0-9]}"
让我们先把数字当作数字,如果可用就使用bc
:
$ t=13.491675
$ read ts fr < <(printf 't=%s; print t/1," ",t-t/1\n' "$t" | bc)
$ echo "$ts + $fr = $t"
13 + .491675 = 13.491675
用awk
:
的计算能力也可以完成同样的事情
$ read ts fr < <(echo "$t" | awk '{printf("%d %f\n", int(), -int())}')
$ echo "$ts + $fr = $t"
13 + 0.491675 = 13.491675
Note the extra leading 0
in the fractional part.
或者混合使用 printf
提取整数部分和 bc
提取小数部分:
$ t=13.491675
$ printf -v ts '%.0f\n' "$t"
$ fr=$(printf '%s-%d\n' "$t" "$i" | bc)
$ echo "$ts + $fr = $t"
13 + .491675 = 13.491675
或者,如果 bc
不是一个选项,printf
和 bash 参数扩展来完成工作:
$ t=13.491675
$ printf -v ts '%.0f\n' "$t"
$ fr="${t#$i}"
$ echo "$ts + $fr = $t"
13 + .491675 = 13.491675
要去掉小数分隔符,如果需要,我们可以再使用一个参数扩展:
$ fr="${fr:1}"
或:
$ fr="${fr:2}"
基于 awk
的解决方案。
使用普通 POSIX 扩展:
#!/usr/bin/env sh
t=13.491675
# Trim-out shortest trailing dot followed by any number of any character
ts=${t%.*}
# Cut shortest leading any number of any character followed by a dot
fr=${t#*.}
# Debug printout
printf 't=%s\nts=%d\nfr=%d\n' "$t" "$ts" "$fr"
或使用 Bash 的此处字符串与 I 内部 F 字段 S分隔符设置为点:
#!/usr/bin/env bash
t=13.491675
IFS=. read -r ts fr <<<"$t"
printf 't=%s\nts=%d\nfr=%d\n' "$t" "$ts" "$fr"
或与 IFS 相同,将未引用的变量拆分为参数
#!/usr/bin/env sh
t=13.491675
# Save IFS
__OIFS="$IFS"
IFS=.
set -- $t
ts=
fr=
IFS=$__OIFS
printf 't=%s\nts=%d\nfr=%d\n' "$t" "$ts" "$fr"
我想分隔一个数字十进制数,将整数部分存储在 bash 变量 ts
中,将小数部分存储在变量 fr
.
进行了参数扩展,但继续获取原始数字。
t=13.491675
ts=${t#![0-9]*}
fr=${t%*![0-9]}
这应该适用于任何 decimal separator:
shopt -s extglob
t=13.491675
ts="${t%%[^0-9]+([0-9])}"
fr="${t##+([0-9])[^0-9]}"
让我们先把数字当作数字,如果可用就使用bc
:
$ t=13.491675
$ read ts fr < <(printf 't=%s; print t/1," ",t-t/1\n' "$t" | bc)
$ echo "$ts + $fr = $t"
13 + .491675 = 13.491675
用awk
:
$ read ts fr < <(echo "$t" | awk '{printf("%d %f\n", int(), -int())}')
$ echo "$ts + $fr = $t"
13 + 0.491675 = 13.491675
Note the extra leading
0
in the fractional part.
或者混合使用 printf
提取整数部分和 bc
提取小数部分:
$ t=13.491675
$ printf -v ts '%.0f\n' "$t"
$ fr=$(printf '%s-%d\n' "$t" "$i" | bc)
$ echo "$ts + $fr = $t"
13 + .491675 = 13.491675
或者,如果 bc
不是一个选项,printf
和 bash 参数扩展来完成工作:
$ t=13.491675
$ printf -v ts '%.0f\n' "$t"
$ fr="${t#$i}"
$ echo "$ts + $fr = $t"
13 + .491675 = 13.491675
要去掉小数分隔符,如果需要,我们可以再使用一个参数扩展:
$ fr="${fr:1}"
或:
$ fr="${fr:2}"
基于 awk
的解决方案。
使用普通 POSIX 扩展:
#!/usr/bin/env sh
t=13.491675
# Trim-out shortest trailing dot followed by any number of any character
ts=${t%.*}
# Cut shortest leading any number of any character followed by a dot
fr=${t#*.}
# Debug printout
printf 't=%s\nts=%d\nfr=%d\n' "$t" "$ts" "$fr"
或使用 Bash 的此处字符串与 I 内部 F 字段 S分隔符设置为点:
#!/usr/bin/env bash
t=13.491675
IFS=. read -r ts fr <<<"$t"
printf 't=%s\nts=%d\nfr=%d\n' "$t" "$ts" "$fr"
或与 IFS 相同,将未引用的变量拆分为参数
#!/usr/bin/env sh
t=13.491675
# Save IFS
__OIFS="$IFS"
IFS=.
set -- $t
ts=
fr=
IFS=$__OIFS
printf 't=%s\nts=%d\nfr=%d\n' "$t" "$ts" "$fr"