【问题标题】:/bin/bash printf does not work with other LANG than C/bin/bash printf 不适用于 C 以外的其他 LANG
【发布时间】:2012-01-13 09:26:33
【问题描述】:

我对 /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 使用 , 而不是 .

【问题讨论】:

    标签: bash locale printf zsh


    【解决方案1】:

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

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

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

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

    【讨论】:

      【解决方案2】:

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

      【讨论】:

      • 我建议设置LC_NUMERIC 而不是LANG,以覆盖用户设置的LC_NUMERIC。甚至是LC_ALL,它胜过所有人。
      【解决方案3】:

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

      【讨论】:

      • 但是,当浮动从 bc 出来时,我该怎么做呢? sed 吗? D:
      • 在这种情况下可能最简单的方法是使用@J-16 的解决方案并强制 LANG=C。
      【解决方案4】:

      您可以使用其他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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-11-20
        • 2016-11-27
        • 2020-03-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-02-14
        相关资源
        最近更新 更多