답변:
로 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
echo 123456789 | awk '$0=gensub(/(...)/,"\\1,","g"){sub(",$",""); print}'
sed
숫자가 정확히 9 자리 인 경우에만 작동합니다. 은 printf
zsh을 작동하지 않습니다. 따라서 두 번째 sed
대답은 아마 최고입니다.
echo 123456789 | awk '{printf ("%'\''d\n", $0)}'
(확실히 Linux에서는 작동하지 않지만! AIX와 Solaris에서는 제대로 작동합니다)
bash
의 printf
지원은 거의 모든 당신은에서 할 수있는 printf
C 기능
type printf # => printf is a shell builtin
printf "%'d" 123456 # => 123,456
printf
coreutils에서 동일한 작업을 수행합니다
/usr/bin/printf "%'d" 1234567 # => 1,234,567
zsh
업데이트 된 게시물에서도 지원 됩니다 .
vsnprintf
. GNU / 리눅스 시스템에서 glibc는 적어도 1995 년 이후로이를 지원 한 것으로 보입니다.
locale -a
. 나는 사용해야했다en_US.utf8
numfmt를 사용할 수 있습니다 :
$ numfmt --grouping 123456789
123,456,789
또는:
$ numfmt --g 123456789
123,456,789
numfmt는 POSIX 유틸리티가 아니며 GNU coreutils의 일부입니다.
-d, --grouping
이중 하이픈 넣기에는 긴 옵션이 필요하므로 다음과 같은 내용을 작성 했습니까?
--g
대신 나를 위해 잘 작동 --grouping
, 즉 numfmt --g 1234567890
와 numfmt --grouping 1234567890
같은 일을한다. 매우 유용한 작은 유틸리티입니다.
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 자리, 왼쪽 그룹은 남아있는 것이지만 적어도 하나의 숫자로 나눕니다. 그런 다음 모든 것이 쉼표로 구분 된 두 그룹으로 대체됩니다. 대체가 실패 할 때까지 계속됩니다. "wpe"옵션은 오류 목록을위한 것이며, 자동 인쇄로 루프 안에 명령문을 묶고 perl "프로그램"으로 다음 인수를 사용하십시오 (자세한 내용은 perldoc perlrun 명령 참조).
최고의 소원 ... 건배, drl
BASH
/ AWK
그가 사용하지 않았을 수 있도록 대안 PERL
전에. 어쨌든, 명령이 무엇을 하는지를 설명하는 것이 가장 좋습니다.
필자의 일반적인 사용 사례는 십진수가 천 단위 구분 기호로 인쇄되도록 명령 파이프 라인의 출력을 수정하는 것입니다. 오히려 함수 나 스크립트를 작성하는 것보다, 나는에 대한 즉시 사용자 정의 할 수있는 기술을 사용하는 것을 선호 어떤 유닉스 파이프 라인의 출력을.
나는 printf
(Awk에서 제공)이 이것을 달성하는 가장 유연하고 기억에 남는 방법이라는 것을 알았습니다 . 아포스트로피 / 작은 따옴표 문자는 POSIX에 의해 10 진수를 형식화하기 위한 수정 자로 지정되며 로케일을 인식하므로 쉼표 문자 사용으로 제한되지 않습니다.
Unix 쉘에서 Awk 명령을 실행할 때 작은 따옴표로 구분 된 문자열 내에 따옴표로 묶는 따옴표 문자를 입력하는 데 어려움이있을 수 있습니다 (예 : 위치 변수의 쉘 확장을 피하기 위해 $1
). 이 경우 작은 따옴표 문자를 입력하는 가장 읽기 쉽고 안정적인 방법은 8 진수 이스케이프 시퀀스로 시작하는 것입니다 (로 시작 함 \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 내부에서 작은 따옴표를 이스케이프 처리하는 방법에 나열되어 있습니다.
참고 : 작은 따옴표 인쇄 에서 경고했듯이 16 진수 이스케이프 시퀀스는 다른 시스템에서 안정적으로 작동하지 않으므로 16 진수 이스케이프 시퀀스를 사용하지 않는 것이 좋습니다.
\047
입니다.
awk
그리고 bash
내장 된 솔루션을 기반으로 좋은이 printf
다른 답변에 설명 된대로. 그러나 먼저 sed
.
를 위해서는 sed
"수동으로"해야합니다. 일반적인 규칙은 4 개의 연속 숫자가 있고 그 뒤에 숫자가 아닌 (또는 줄 끝) 있으면 첫 번째 숫자와 두 번째 숫자 사이에 쉼표를 삽입해야한다는 것입니다.
예를 들어
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
$ echo 1232323 | awk '{printf(fmt,$1)}' fmt="%'6.3f\n"
12,32,323.000
BIG 번호를보고있는 경우 위의 솔루션을 작동시킬 수 없었습니다. 예를 들어 정말 큰 숫자를 얻습니다.
$ echo 2^512 |bc -l|tr -d -c [0-9]
13407807929942597099574024998205846127479365820592393377723561443721764030073546976801874298166903427690031858186486050853753882811946569946433649006084096
참고 tr
BC에서 백 슬래시 줄 바꿈 출력을 제거 해야합니다 . 이 숫자는 awk의 부동 소수점 또는 고정 비트 숫자로 취급하기에는 너무 커서 sed의 모든 숫자를 설명하기에 충분한 정규 표현식을 작성하고 싶지 않습니다. 오히려 나는 그것을 뒤집어서 세 자리 그룹 사이에 쉼표를 넣은 다음 반전시킬 수 있습니다.
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
awk: run time error: improper conversion(number 1) in printf("%'d
.
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
sed 's/^,//g'
있습니다.
I는 부분하고 싶어 후 소수 구분 올바르게 / 분리 이격 따라서 I 지역 및 개인 환경에 적응 일부 쉘 변수를 사용하여이 나오지 스크립트를 썼다. 또한 함께 그룹화 된 자릿수에 대한 다른 규칙을 고려 합니다 .
#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'
}
숫자의 길이에 관계없이 작동 하고 로케일의 설정에 관계없이 사용 되는 bash
/ awk
(요청에 따라) 솔루션 은 숫자가 입력 위치에 있고 다음에 천 단위 구분 기호를 추가하지 않는 :,
thousands_sep
1.12345
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]+/
echo 123456789 | awk '$0=gensub(/(...)/,"\\1,","g")'