Pythonで
re.sub(r"(?<=.)(?=(?:...)+$)", ",", stroke )
トリプレットで数値を分割するには、例えば:
echo 123456789 | python -c 'import sys;import re; print re.sub(r"(?<=.)(?=(?:...)+$)", ",", sys.stdin.read());'
123,456,789
Bash/awkで同じことをするには?
sed
の場合:
$ echo "123456789" | sed 's/\([[:digit:]]\{3\}\)\([[:digit:]]\{3\}\)\([[:digit:]]\{3\}\)/\1,\2,\3/g'
123,456,789
(これは正確に9桁でのみ機能することに注意してください!)
またはこれとsed
:
$ echo "123456789" | sed ':a;s/\B[0-9]\{3\}\>/,&/;ta'
123,456,789
printf
の場合:
$ LC_NUMERIC=en_US printf "%'.f\n" 123456789
123,456,789
bash
のprintf
は、printf
C関数で実行できるほとんどすべての機能をサポートします
type printf # => printf is a Shell builtin
printf "%'d" 123456 # => 123,456
coreutilsのprintf
も同じです
/usr/bin/printf "%'d" 1234567 # => 1,234,567
Numfmtを使用できます。
$ numfmt --grouping 123456789
123,456,789
または:
$ numfmt --g 123456789
123,456,789
NumfmtはPOSIXユーティリティではなく、GNU coreutilsの一部です。
cat <<'EOF' |
13407807929942597099574024998205846127479365820592393377723561443721764030073546976801874298166903427690031858186486050853753882811946569946433649006084096
EOF
Perl -wpe '1 while s/(\d+)(\d\d\d)/$1,$2/;'
生成する:
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
これは、数字の文字列を2つのグループに分割することによって実現されます。右側のグループは3桁、左側のグループは残りの数字ですが、少なくとも1桁です。次に、すべてがコンマで区切られた2つのグループに置き換えられます。これは、置換が失敗するまで続きます。オプション "wpe"はエラーリスト用で、ステートメントをループ内で自動印刷で囲み、次の引数をPerl "プログラム"として受け取ります(詳細については、コマンドperldoc perlrunを参照してください)。
最高の願い...乾杯、drl
いくつかのawk
実装:
echo "123456789" | awk '{ printf("%'"'"'d\n",$1); }'
123,456,789
"%'"'"'d\n"
is:"%
(single quote)(double quote)(single quote)(double quote)(single quote)d\n"
これは、ロケールに構成された1000の区切り文字を使用します(通常、英語ロケールでは,
、フランス語ではスペース、スペイン語/ドイツ語では.
)。 locale thousands_sep
から返されるものと同じ
awk
とbash
には、他の回答で説明されているように、printf
に基づく優れた組み込みソリューションがあります。しかし、最初にsed
です。
sed
の場合は、「手動」で行う必要があります。一般的な規則は、4つの連続する数字があり、その後に非数字(または行末)が続く場合、最初と2番目の数字の間にコンマを挿入する必要があるということです。
例えば、
echo 12345678 | sed -re 's/([0-9])([0-9]{3})($|[^0-9])/\1,\2\3/'
印刷します
12345,678
十分な数のコンマを追加し続けるために、プロセスを繰り返し続ける必要があることは明らかです。
sed -re ' :restart ; s/([0-9])([0-9]{3})($|[^0-9])/\1,\2\3/ ; t restart '
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
私の一般的な使用例は、コマンドパイプラインの出力を変更して、10進数が1000のセパレータで出力されるようにすることです。関数やスクリプトを作成するのではなく、Unixパイプラインからのany出力をその場でカスタマイズできる手法を使用することを好みます。
私はprintf
(Awkが提供)が最も柔軟で、これを実現するための記憶に残る方法であることがわかりました。アポストロフィ/一重引用符文字は、10進数をフォーマットするために [〜#〜] posix [〜#〜] として 修飾子 として指定され、ロケールに対応しているという利点がありますしたがって、コンマ文字の使用に限定されません。
UnixシェルからAwkコマンドを実行する場合、単一引用符で区切られた文字列内に一重引用符文字を入力するのは困難な場合があります(位置変数のシェル拡張を回避するために、$1
など)。この場合、一重引用符文字を入力する最も読みやすく信頼できる方法は、octalエスケープシーケンス(\0
で始まる)として入力することです。 )。
例:
printf "first 1000\nsecond 10000000\n" |
awk '{printf "%9s: %11\047d\n", $1, $2}'
first: 1,000
second: 10,000,000
最も多くのディスク領域を使用しているディレクトリを示すパイプラインのシミュレーション出力:
printf "7654321 /home/export\n110384 /home/incoming\n" |
awk '{printf "%22s: %9\047d\n", $2, $1}'
/home/export: 7,654,321
/home/incoming: 110,384
他の解決策は awk内の単一引用符をエスケープする方法 にリストされています。
注: Print Single Single Quote で警告されているように、16進数のエスケープシーケンスは異なるシステム間で確実に機能しないため、使用を避けることをお勧めします。
数値の長さに関係なく機能し、ロケールの_,
_設定に関係なく_thousands_sep
_を使用するbash
/awk
ソリューション(および要求されたとおり)ソリューション、および数値入力内にあり、_1.12345
_の後に1000の区切り文字を追加しないようにします。
_echo not number 123456789012345678901234567890 1234.56789 |
awk '{while (match($0, /(^|[^.0123456789])[0123456789]{4,}/))
$0 = substr($0, 1, RSTART+RLENGTH-4) "," substr($0, RSTART+RLENGTH-3)
print}'
_
与える:
_not number 123,456,789,012,345,678,901,234,567,890 1,234.56789
_
インターバル正規表現演算子をサポートしないawk
のようなmawk
実装では、正規表現を/(^|[^.0123456789])[0123456789][0123456789][0123456789][0123456789]+/
に変更します
a="13407807929942597099574024998205846127479365820592393377723561443721764030073546976801874298166903427690031858186486050853753882811946569946433649006084096"
echo "$a" | rev | sed "s#[[:digit:]]\{3\}#&,#g" | rev
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
$ echo 1232323 | awk '{printf(fmt,$1)}' fmt="%'6.3f\n"
12,32,323.000
あなたが大きな数字を見ているならば、私は上記の解決策を機能させることができませんでした。たとえば、本当に大きな数を取得しましょう:
_$ echo 2^512 |bc -l|tr -d -c [0-9] 13407807929942597099574024998205846127479365820592393377723561443721764030073546976801874298166903427690031858186486050853753882811946569946433649006084096
_
Bcからバックスラッシュの改行出力を削除するには、tr
が必要です。この数値は大きすぎてawkで浮動小数点数または固定ビット数として扱うことができません。また、sedのすべての数字を説明するのに十分な大きさの正規表現を作成したくありません。むしろ、それを逆にして、3桁のグループの間にカンマを入れてから、元に戻すことができます。
echo 2^512 |bc -l|tr -d -c [0-9] |rev |sed -e 's/\([0-9][0-9][0-9]\)/\1,/g' |rev 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
また、afterdecimal separator の部分を正しく分離/配置したかったので、このsed-scriptを作成しました。地域や個人の好みに合わせて調整するシェル変数。また、異なる グループ化された桁数の規則 も考慮に入れます。
#DECIMALSEP='.' # usa
DECIMALSEP=',' # europe
#THOUSSEP=',' # usa
#THOUSSEP='.' # europe
#THOUSSEP='_' # underscore
#THOUSSEP=' ' # space
THOUSSEP=' ' # thinspace
# group before decimal separator
#GROUPBEFDS=4 # china
GROUPBEFDS=3 # europe and usa
# group after decimal separator
#GROUPAFTDS=5 # used by many publications
GROUPAFTDS=3
function digitgrouping {
sed -e '
s%\([0-9'"$DECIMALSEP"']\+\)'"$THOUSSEP"'%\1__HIDETHOUSSEP__%g
:restartA ; s%\([0-9]\)\([0-9]\{'"$GROUPBEFDS"'\}\)\(['"$DECIMALSEP$THOUSSEP"']\)%\1'"$THOUSSEP"'\2\3% ; t restartA
:restartB ; s%\('"$DECIMALSEP"'\([0-9]\{'"$GROUPAFTDS"'\}\'"$THOUSSEP"'\)*\)\([0-9]\{'"$GROUPAFTDS"'\}\)\([0-9]\)%\1\3'"$THOUSSEP"'\4% ; t restartB
:restartC ; s%\([^'"$DECIMALSEP"'][0-9]\+\)\([0-9]\{'"$GROUPBEFDS"'\}\)\($\|[^0-9]\)%\1'"$THOUSSEP"'\2\3% ; t restartC
s%__HIDETHOUSSEP__%\'"$THOUSSEP"'%g'
}