जवाबों:
के साथ 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)}'
(जो जाहिर तौर पर लिनक्स पर काम नहीं करता है!?, लेकिन AIX और सोलारिस पर ठीक काम करता है)
bash
के printf
समर्थन काफी सब कुछ आप में कर सकते हैं printf
सी समारोह
type printf # => printf is a shell builtin
printf "%'d" 123456 # => 123,456
printf
coreutils से ही करेंगे
/usr/bin/printf "%'d" 1234567 # => 1,234,567
vsnprintf
। GNU / Linux सिस्टम पर, glibc कम से कम 1995 के बाद से इसका समर्थन करता प्रतीत होता है।
export LC_NUMERIC="en_US"
तो अल्पविराम के लिए मजबूर कर सकते हैं।
locale -a
। मैं का इस्तेमाल किया थाen_US.utf8
आप numfmt का उपयोग कर सकते हैं:
$ numfmt --grouping 123456789
123,456,789
या:
$ numfmt --g 123456789
123,456,789
ध्यान दें कि numfmt एक POSIX उपयोगिता नहीं है, यह GNU कोरुटिल्स का हिस्सा है।
-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 अंकों के साथ दाहिने हाथ का समूह, जो भी रहता है उसके साथ बाएं हाथ का समूह, लेकिन कम से कम एक अंक। फिर सब कुछ 2 समूहों द्वारा बदल दिया जाता है, एक अल्पविराम द्वारा अलग किया जाता है। यह तब तक जारी रहता है जब तक प्रतिस्थापन विफल हो जाता है। विकल्प "वेप" त्रुटि लिस्टिंग के लिए हैं, एक लूप के अंदर स्टेटमेंट को एक स्वचालित प्रिंट के साथ संलग्न करें, और अगले तर्क को पर्ल "प्रोग्राम" के रूप में लें (विवरण के लिए कमांड perldoc perlrun देखें)।
शुभकामनाएँ ... चीयर्स, डीएल
BASH
/ AWK
विकल्प मांगा ताकि वह PERL
पहले उपयोग न कर सके । किसी भी मामले में, यह समझाने के लिए कि कमांड क्या करता है - विशेष रूप से एक-लाइनर्स के लिए।
कुछ awk
कार्यान्वयन के साथ :
echo "123456789" | awk '{ printf("%'"'"'d\n",$1); }'
123,456,789
"%'"'"'d\n"
है: "%
(एकल उद्धरण) (डबल उद्धरण) (एकल उद्धरण) (डबल उद्धरण) (एकल उद्धरण) d \ n"
यह आपके लोकेल के लिए कॉन्फ़िगर किए गए हजार विभाजक (आमतौर ,
पर अंग्रेजी स्थानों में, फ्रेंच में स्थान, .
स्पेनिश / जर्मन में) का उपयोग करेगा। उसी के अनुसार लौटाlocale thousands_sep
मेरे लिए एक सामान्य उपयोग का मामला एक कमांड पाइपलाइन के आउटपुट को संशोधित करना है ताकि दशमलव संख्या हजार विभाजक के साथ मुद्रित हो। एक फ़ंक्शन या स्क्रिप्ट लिखने के बजाय, मैं एक ऐसी तकनीक का उपयोग करना पसंद करता हूं जिसे मैं यूनिक्स पाइपलाइन से किसी भी आउटपुट के लिए मक्खी पर अनुकूलित कर सकता हूं ।
मैंने इसे printf
पूरा करने के लिए सबसे अधिक लचीला और यादगार तरीका (Awk द्वारा प्रदान) पाया है । Apostrophe / एकल उद्धरण चरित्र POSIX द्वारा दशमलव संख्याओं को प्रारूपित करने के लिए एक संशोधक के रूप में निर्दिष्ट किया गया है और इसका लाभ यह है कि यह स्थानीय-जागरूक है इसलिए यह अल्पविराम वर्णों का उपयोग करने के लिए प्रतिबंधित नहीं है।
जब यूनिक्स शेल से Awk कमांड्स चल रहे हों, तो सिंगल-कोट्स द्वारा सीलिंग किए गए स्ट्रिंग के अंदर एक सिंग-कोट कैरेक्टर में प्रवेश करने में कठिनाइयाँ हो सकती हैं (पोजिशनल वेरिएबल्स के शेल विस्तार से बचने के लिए, जैसे $1
)। इस मामले में, मुझे एकल-उद्धरण चरित्र में प्रवेश करने के लिए सबसे पठनीय और विश्वसनीय तरीका मिला है, इसे एक ऑक्टल एस्केप सीक्वेंस (शुरुआत के साथ \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
अन्य समाधानों को सूचीबद्ध किया गया है कि कैसे जाग के अंदर एक उद्धरण से बचने के लिए ।
नोट: जैसा कि प्रिंट एक एकल उद्धरण में चेतावनी दी गई है , यह हेक्साडेसिमल एस्केप अनुक्रमों के उपयोग से बचने के लिए अनुशंसित है क्योंकि वे विभिन्न प्रणालियों में मज़बूती से काम नहीं करते हैं।
\047
।
awk
और bash
अच्छे अंतर्निर्मित समाधान हैं, printf
जो अन्य उत्तरों में वर्णित के आधार पर हैं । लेकिन पहले, sed
।
इसके लिए sed
, हमें इसे "मैन्युअल रूप से" करने की आवश्यकता है। सामान्य नियम यह है कि यदि आपके पास लगातार चार अंक हैं, उसके बाद एक गैर-अंक (या अंत-पंक्ति) तो पहले और दूसरे अंक के बीच एक अल्पविराम डाला जाना चाहिए।
उदाहरण के लिए,
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
, ताकि वह वापस कूद जाए।
यहाँ एक बश डेमो ( 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 से बैकस्लैश न्यूलाइन आउटपुट निकालने की आवश्यकता है । यह संख्या बहुत बड़ी है, जो जागने में फ्लोट या निश्चित बिट संख्या के रूप में माना जाता है, और मैं यह भी नहीं चाहता कि बड़े पैमाने पर सभी अंकों के लिए एक रेक्सएक्सपी का निर्माण किया जाए। इसके बजाय, मैं इसे उल्टा कर सकता हूं और तीन अंकों के समूहों के बीच अल्पविराम लगा सकता हूं, फिर इसे हटा दें:
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'
।
मैं भी भाग करना चाहते थे के बाद दशमलव विभाजक सही ढंग से अलग हो / स्थान दिया गया है, इसलिए मैं इस sed स्क्रिप्ट जो क्षेत्रीय और व्यक्तिगत वरीयताओं को समायोजित करने के लिए कुछ खोल चर का उपयोग करता है लिखा था। यह एक साथ समूहीकृत अंकों की संख्या के लिए विभिन्न सम्मेलनों को भी ध्यान में रखता है :
#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
अंतराल रेगेक्स ऑपरेटरों का समर्थन नहीं करते हैं, regexp को बदल दें/(^|[^.0123456789])[0123456789][0123456789][0123456789][0123456789]+/
echo 123456789 | awk '$0=gensub(/(...)/,"\\1,","g")'