分隔十进制数的整数和小数部分

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"