0

我必须用 gawk 处理一些巨大的文件。我的主要问题是我必须使用千位分隔符打印一些浮点数。例如:10000应该在输出中显示为10.000和。10000,0110.000,01

我(和谷歌)想出了这个函数,但是对于浮点数失败了:

function commas(n) {
  gsub(/,/,"",n)
  point = index(n,".") - 1
  if (point < 0) point = length(n)
    while (point > 3) {
      point -= 3
      n = substr(n,1,point)"."substr(n,point + 1)
    }
  sub(/-\./,"-",n)
  return d n
}

但它因浮动而失败。

现在我正在考虑将输入拆分为一个整数和一个 < 1 部分,然后在格式化整数之后再次粘合它们,但是没有更好的方法吗?

免责声明:

  • 我不是程序员
  • 我通过一些 SHELL 环境知道这一点。可以设置千位分隔符的变量,但它必须在具有不同语言和/或语言环境设置的不同环境中工作。
  • 英语是我的第二语言,如果我用错了,请见谅
4

2 回答 2

2

它因浮点数而失败,因为您正在传递欧洲类型的数字(1.000.000,25 代表一百万零四分之一)。如果您只是更改逗号和句点,则您提供的功能应该可以工作。我会先用 1000000.25 测试当前版本,看看它是否适用于非欧洲数字。

可以调用以下 awk 脚本"echo 1 | awk -f xx.gawk",它将向您展示“正常”和欧洲版本的运行情况。它输出:

123,456,789.1234
123.456.789,1234

显然,您只对函数感兴趣,实际代码将使用输入流将值传递给函数,而不是固定字符串。

function commas(n) {
    gsub(/,/,"",n)
    point = index(n,".") - 1
    if (point < 0) point = length(n)
    while (point > 3) {
        point -= 3
        n = substr(n,1,point)","substr(n,point + 1)
    }
    return n
}
function commaseuro(n) {
    gsub(/\./,"",n)
    point = index(n,",") - 1
    if (point < 0) point = length(n)
    while (point > 3) {
        point -= 3
        n = substr(n,1,point)"."substr(n,point + 1)
    }
    return n
}
{ print commas("1234,56789.1234") "\n" commaseuro("12.3456789,1234") }

除了对逗号和句点的处理之外,这些功能是相同的。在以下描述中,我们将它们称为分隔符和小数:

  • gsub 删除所有现有的分隔符,因为我们将把它们放回去。
  • point 找到小数点在哪里,因为那是我们的起点。
  • 如果没有小数,则 if 语句从末尾开始。
  • 我们在剩下三个以上字符时循环。
  • 在循环内部,我们调整插入分隔符的位置,并插入它。
  • 循环完成后,我们返回调整后的值。
于 2009-04-15T11:08:03.277 回答
0

Pax的回答一起去:

阅读GNU awk 手册的“转换”部分,其中明确讨论了LOCALE环境变量对数字类型的字符串表示的影响。

于 2009-04-15T13:00:48.373 回答