/bin/bash printf 不适用于 C 以外的其他 LANG

发布于 2024-12-26 12:09:13 字数 660 浏览 2 评论 0原文

我对 /bin/bash 和使用 printf 格式化字符串的脚本有一个非常奇怪的问题。

我的脚本看起来像这样

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

,但不同之处在于我计算了上面的数字 13.23...。当我使用 /usr/bin/zsh 时效果很好!甚至 /bin/sh 也可以做到(但它不能做 if 的东西......) 最大的问题是 /bin/bash 似乎不理解 printf 或者当我不使用 LANG=C 时确实有另一种格式化方式。

我的 LANG 变量设置为 de_AT.UTF-8 然后我收到此错误:

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

所以它只是说我给 printf 的数字无效...

我需要以不同的方式运行 printf ?

编辑:问题似乎在于数字的计算:

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

我如何告诉 bc 使用 , 而不是 .

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 .?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

八巷 2025-01-02 12:09:13

您的问题源于 LC_NUMERIC 设置,bash 在解析 printf 参数时遵循该设置。

我觉得这种行为很可疑。 Ksh93 还根据 LC_NUMERIC 解析数字,而 pdksh 和 dash 需要一个点作为参数中的分隔符,而 zsh 接受点或本地格式。 POSIX 没有说,因为指定的浮点格式是可选的printf (但在打印数字时必须遵守LC_NUMERIC)。

作为用户,我建议永远不要设置 LC_NUMERICLC_COLLATE ,除非在非常特定的情况下,您确定需要它们的行为。这意味着不使用 LAN 而是设置特定类别;大多数人只需要LC_CTYPE(字符编码)、LC_MESSAGES(消息语言)和LC_TIME(日期和时间格式)。在脚本中,您可以通过设置 LC_ALL 覆盖所有类别,也可以通过设置特定类别(设置 LANG 仅覆盖 $LANG 而不会覆盖用户设置的$LC_NUMERIC)。

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

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
弥枳 2025-01-02 12:09:13

只需执行 $(LANG=C printf "%.3f" 13.234324245),只需在此命令上设置 LANG

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

嘿嘿嘿 2025-01-02 12:09:13

这可能是一个区域设置问题 - 我认为在德语中,小数点分隔符是逗号 , 而不是句点 .。尝试使用 13,234324245 作为您的值。

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.

牵你的手,一向走下去 2025-01-02 12:09:13

您可以使用其他 printf 实现: 使用非内置 /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

使用 zsh 内置 printf 实现:

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

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文