/bin/bash printf does not work with other LANG than C

六眼飞鱼酱① 提交于 2019-12-10 13:56:19

问题


I have a really weird problem with /bin/bash and a script that uses printf to format a string.

My script looks like this

rt=$(printf "%.3f" 13.234324245)

with the difference, that i compute the number 13.23... above. When i use /usr/bin/zsh that works great! Even /bin/sh can do it (but it cant do the if stuff...) The biggest problem ist that /bin/bash seems to does not understand printf or does have another formating way when i dont use LANG=C.

My LANG Variable is set to de_AT.UTF-8 and then i get this Error:

/path/to/script: Zeile 12: printf: 13.234324245: Ungültige Zahl.

So it simply says that the number i gave printf is invalid...

Do i need to run printf in a different way?

edit: The problem seems to be on the computation of the number:

rt=$(printf "%.3f" $(echo "$res2 - $res1"|bc ))

how i can tell bc to use a , instead of .?


回答1:


Your problem stems for the LC_NUMERIC setting, which bash follows when parsing arguments to printf.

I find this behavior dubious. Ksh93 also parses numbers according to LC_NUMERIC while pdksh and dash want a dot as the separator in the argument, and zsh accepts either a dot or the local format. POSIX doesn't say, because the floating point format specified are optional in printf (LC_NUMERIC must be respected when printing numbers though).

As a user I recommend never setting LC_NUMERIC and LC_COLLATE except in very specific circumstances where you're sure you want their behavior. This means not using LANG and setting specific categories instead; most people only need LC_CTYPE (character encoding), LC_MESSAGES (language of messages) and LC_TIME (date and time format). In a script, you can override all categories by setting LC_ALL, or a specific category by setting it (setting LANG only overrides $LANG and not a user-set $LC_NUMERIC).

#!/bin/sh
LC_NUMERIC=C LC_COLLATE=C
printf "%.3f" 13.234324245



回答2:


It's probably a locale issue - I think that in German the decimal separator is comma , rather than period .. Try using 13,234324245 as your value.




回答3:


Just do a $(LANG=C printf "%.3f" 13.234324245), just set LANG on this command




回答4:


You can use other printf implementations: with non-builtin /usr/bin/printf:

% # LANG is ru_RU.UTF8, decimal separator is comma
% /usr/bin/printf %.3f 3.14
3,140
% /usr/bin/printf %.3f 3,14
/usr/bin/printf: 3,14: значение преобразовано не полностью
3,000
% LANG=C /usr/bin/printf %.3f 3,14
printf: 3,14: value not completely converted
3.00

With zsh built-in printf implementation:

% printf %.3f 3.14
3,140
% printf %.3f 3,14
3,140


来源:https://stackoverflow.com/questions/8848335/bin-bash-printf-does-not-work-with-other-lang-than-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!