5

如果我没记错的话,awk 会根据操作系统语言解析一个数字(例如,echo "1,2" | awk '{printf("%f\n",$1)}'在英语系统中将被解释为 1,而在逗号将整数与小数部分分开的系统中会被解释为 1.2)。

我不知道 C printf 是否也这样做,所以我添加了 C 标签。

我想修改前面的命令,使其返回相同的值 (1.2),而不管使用的系统如何。

4

2 回答 2

8

欢迎来到语言环境的丑陋。要解决您的问题,首先将语言环境设置为 C 语言。

export LC_NUMERIC=C
echo "1,2" | awk '...your code...'

要关闭其他依赖于语言环境的愚蠢行为,您可以

export LC_ALL=C
于 2012-04-25T17:04:37.050 回答
3

如果您正在使用gawk,则可以使用该--use-lc-numeric选项。

$ LC_NUMERIC=de_DE.UTF-8 awk 'BEGIN {printf("%f\n", "1,2")}'
1.000000
$ LC_NUMERIC=de_DE.UTF-8 awk --use-lc-numeric 'BEGIN {printf("%f\n", "1,2")}'
1,200000

来自 GAWK 手册

POSIX 标准规定,在读取 awk 程序源代码和命令行变量赋值时,awk 始终使用句点作为小数点(请参阅其他参数)。但是,在解释输入数据时,对于 print 和 printf 输出,以及对于数字到字符串的转换,使用本地小数点字符。以下是一些说明 GNU/Linux 系统上行为差异的示例:

 $ gawk 'BEGIN { printf "%g\n", 3.1415927 }'
 -| 3.14159
 $ LC_ALL=en_DK gawk 'BEGIN { printf "%g\n", 3.1415927 }'
 -| 3,14159
 $ echo 4,321 | gawk '{ print $1 + 1 }'
 -| 5
 $ echo 4,321 | LC_ALL=en_DK gawk '{ print $1 + 1 }'
 -| 5,321

'en_DK' 语言环境适用于丹麦的英语,其中逗号充当小数点分隔符。在正常的“C”语言环境中,gawk 将“4,321”视为“4”,而在丹麦语言环境中,将其视为完整数字 4.321。

一些早期版本的 gawk 完全符合标准的这一方面。然而,许多非英语语言环境的用户抱怨这种行为,因为他们的数据使用句点作为小数点,因此恢复默认行为以使用句点作为小数点字符。您可以使用该--use-lc-numeric选项(请参阅选项)强制 gawk 使用区域设置的小数点字符。(在 POSIX 模式下,gawk 也使用区域设置的小数点字符,或者 via --posix,或者POSIXLY_CORRECT环境变量。)

我得到了类似的行为/usr/bin/printf

$ LC_NUMERIC=de_DE.UTF-8 /usr/bin/printf "%f\n" "1,2"
/usr/bin/printf: 1,2: value not completely converted
1,000000
$ LC_NUMERIC=de_DE.UTF-8 /usr/bin/printf "%f\n" "1.2"
1,200000

但没有能力覆盖它。

如果您的意图相反,即采用“欧洲”输入并输出“美国”数字,您将需要使用更强大的东西。可能的 Python 或 Perl 及其语言环境模块。

于 2012-04-25T19:16:20.567 回答