awk减少了系统依赖性

时间:2012-04-25 17:01:55

标签: c bash awk

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

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

我想修改上一个命令,使其无论使用何种系统都返回相同的值(1.2)。

2 个答案:

答案 0 :(得分:8)

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

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

要关闭其他依赖于语言环境的tomfoolery,您可以

export LC_ALL=C

答案 1 :(得分:2)

如果您使用的是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 manual

  

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使用locale的小数点字符。 (gawk也   在POSIX模式下使用locale的小数点字符   通过--posixPOSIXLY_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及其语言环境模块。