在数字中添加千位分隔符

use*_*496 53 bash awk string shell-script

在蟒蛇中

 re.sub(r"(?<=.)(?=(?:...)+$)", ",", stroke ) 
Run Code Online (Sandbox Code Playgroud)

用三元组分割一个数字,例如:

 echo 123456789 | python -c 'import sys;import re; print re.sub(r"(?<=.)(?=(?:...)+$)", ",",  sys.stdin.read());'
 123,456,789
Run Code Online (Sandbox Code Playgroud)

如何用 bash/awk 做同样的事情?

Mik*_*kel 61

bashprintf支持几乎所有您可以在printfC 函数中执行的操作

type printf           # => printf is a shell builtin
printf "%'d" 123456   # => 123,456
Run Code Online (Sandbox Code Playgroud)

printf 来自 coreutils 也会做同样的事情

/usr/bin/printf "%'d" 1234567   # => 1,234,567
Run Code Online (Sandbox Code Playgroud)

  • 我使用的是 bash 4.1.2,它不支持...:( (2认同)
  • 注意 printf 使用千位 [separator for your current locale](https://www.cyberciti.biz/faq/unix-linux-bash-number-formatting-in-with-thousand-separator/),这可能是一个逗号、点或什么都没有。如果你想强制使用逗号,你可以`export LC_NUMERIC="en_US"`。 (2认同)
  • 使用“locale -a”获取支持的语言环境列表。我必须使用`en_US.utf8` (2认同)

slm*_*slm 42

sed

$ echo "123456789" | sed 's/\([[:digit:]]\{3\}\)\([[:digit:]]\{3\}\)\([[:digit:]]\{3\}\)/\1,\2,\3/g'
123,456,789
Run Code Online (Sandbox Code Playgroud)

(请注意,这仅适用于 9 位数字!)

或者这与sed

$ echo "123456789" | sed ':a;s/\B[0-9]\{3\}\>/,&/;ta'
123,456,789
Run Code Online (Sandbox Code Playgroud)

printf

$ LC_NUMERIC=en_US printf "%'.f\n" 123456789
123,456,789
Run Code Online (Sandbox Code Playgroud)


Ste*_*nny 15

您可以使用 numfmt:

$ numfmt --grouping 123456789
123,456,789
Run Code Online (Sandbox Code Playgroud)

或者:

$ numfmt --g 123456789
123,456,789
Run Code Online (Sandbox Code Playgroud)

请注意,numfmt 不是 POSIX 实用程序,它是 GNU coreutils 的一部分。

  • 只是不要在脚本中使用缩写形式,因为有一天,您使用的形式可能会停止工作。 (2认同)

drl*_*drl 6

cat <<'EOF' |
13407807929942597099574024998205846127479365820592393377723561443721764030073546976801874298166903427690031858186486050853753882811946569946433649006084096
EOF
perl -wpe '1 while s/(\d+)(\d\d\d)/$1,$2/;'
Run Code Online (Sandbox Code Playgroud)

产生:

13,407,807,929,942,597,099,574,024,998,205,846,127,479,365,820,592,393,377,723,561,443,721,764,030,073,546,976,801,874,298,166,903,427,690,031,858,186,486,050,853,753,882,811,946,569,946,433,649,006,084,096
Run Code Online (Sandbox Code Playgroud)

这是通过将数字串分成 2 组来实现的,右手组有 3 个数字,左手组有剩下的任何数字,但至少有一个数字。然后一切都被 2 个组替换,用逗号分隔。这一直持续到替换失败。选项“wpe”用于错误列表,将语句括在循环内并带有自动打印,并将下一个参数作为 perl“程序”(有关详细信息,请参阅命令 perldoc perlrun)。

最好的祝福......干杯,博士


Aar*_*aid 5

awkbash有良好的内置解决方案,基于printf,如其他答案中所述。但首先,sed

对于sed,我们需要“手动”进行。一般规则是,如果有四个连续数字,后跟一个非数字(或行尾),则应在第一个和第二个数字之间插入逗号。

例如,

echo 12345678 | sed -re 's/([0-9])([0-9]{3})($|[^0-9])/\1,\2\3/'
Run Code Online (Sandbox Code Playgroud)

将打印

12345,678
Run Code Online (Sandbox Code Playgroud)

显然,我们需要不断重复这个过程,以便不断添加足够的逗号。

sed -re ' :restart ; s/([0-9])([0-9]{3})($|[^0-9])/\1,\2\3/ ; t restart '
Run Code Online (Sandbox Code Playgroud)

在 中sed,该命令指定一个标签,如果最后一个命令成功,t将跳转到该标签。s///因此,我用 , 定义了一个标签:restart,以便它跳回来。

这是一个 bash 演示(在ideone上),适用于任意数量的数字:

function thousands {
    sed -re ' :restart ; s/([0-9])([0-9]{3})($|[^0-9])/\1,\2\3/ ; t restart '
}                                                 
echo 12 | thousands
echo 1234 | thousands
echo 123456 | thousands
echo 1234567 | thousands
echo 123456789 | thousands
echo 1234567890 | thousands
Run Code Online (Sandbox Code Playgroud)