LinuxQuestions.org
Review your favorite Linux distribution.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 09-24-2008, 06:11 AM   #1
KClaisse
LQ Newbie
 
Registered: Jul 2007
Posts: 7

Rep: Reputation: 0
Format numbers using bash?


I am trying to find a way to convert large numbers into comma separated numbers using bash. I.e. 12345 -> 12,345 I tried using the printf solution: printf "%'d\n" 12345678 but it doesn't seem to work in Cygwin (probably because locale isn't supported yet). Is there a way to do this within bash?

Last edited by KClaisse; 09-24-2008 at 06:17 AM.
 
Old 09-24-2008, 06:50 AM   #2
ChrisAbela
Member
 
Registered: Mar 2008
Location: Malta
Distribution: Slackware
Posts: 572

Rep: Reputation: 154Reputation: 154
num=12345
echo "${num%???},${num#??}"
 
Old 09-24-2008, 07:22 AM   #3
ghostdog74
Senior Member
 
Registered: Aug 2006
Posts: 2,697
Blog Entries: 5

Rep: Reputation: 244Reputation: 244Reputation: 244
Quote:
Originally Posted by ChrisAbela View Post
num=12345
echo "${num%???},${num#??}"
this is not enough. num may not be 12345 everytime.
 
Old 09-24-2008, 07:25 AM   #4
theYinYeti
Senior Member
 
Registered: Jul 2004
Location: France
Distribution: Arch Linux
Posts: 1,897

Rep: Reputation: 66
What exactly are you trying to achieve? How should 12345678 be rendered?

Yves.
 
Old 09-24-2008, 07:26 AM   #5
ghostdog74
Senior Member
 
Registered: Aug 2006
Posts: 2,697
Blog Entries: 5

Rep: Reputation: 244Reputation: 244Reputation: 244
Quote:
Originally Posted by KClaisse View Post
I am trying to find a way to convert large numbers into comma separated numbers using bash. I.e. 12345 -> 12,345 I tried using the printf solution: printf "%'d\n" 12345678 but it doesn't seem to work in Cygwin (probably because locale isn't supported yet). Is there a way to do this within bash?
if you have Python and can use it, here's an alternative
Code:
#!/usr/bin/env python
import locale
locale.setlocale(locale.LC_ALL,('en','ascii')) 
print locale.format('%.2f', 5554435.555, 3)
output
Code:
# ./test.py
5,554,435.55
 
Old 09-24-2008, 07:35 AM   #6
theYinYeti
Senior Member
 
Registered: Jul 2004
Location: France
Distribution: Arch Linux
Posts: 1,897

Rep: Reputation: 66
Oh I just understood! In most of the world (or so I've read), and at least where I live, the comma stands for the decimal separator. I suppose “your” comma is a thousands separator, isn't it?

Yves.
 
Old 09-24-2008, 07:41 AM   #7
chrism01
LQ Guru
 
Registered: Aug 2004
Location: Sydney
Distribution: Rocky 9.2
Posts: 18,356

Rep: Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751Reputation: 2751
In the English speaking world your 2nd sentence is the case

PS re OP: That does work in bash:

printf "%'d\n" 12345678
12,345,678

Last edited by chrism01; 09-24-2008 at 07:44 AM.
 
Old 09-25-2008, 02:05 AM   #8
KClaisse
LQ Newbie
 
Registered: Jul 2007
Posts: 7

Original Poster
Rep: Reputation: 0
Quote:
Originally Posted by chrism01 View Post
In the English speaking world your 2nd sentence is the case

PS re OP: That does work in bash:

printf "%'d\n" 12345678
12,345,678
Unfortunately that relies on locale which isn't available in Cygwin, although it works fine on a normal box. I'm just looking to format the output of any number, no decimals among then, to include comma's for presentation purposes. There are thousands of numbers so I cannot do them by hand. Here's an example:

1 = 1
10 = 10
100 = 100
1000 = 1,000
10000 = 10,000
100000 = 100,000
1000000 = 1,000,000

etc.
 
Old 09-25-2008, 08:29 AM   #9
archtoad6
Senior Member
 
Registered: Oct 2004
Location: Houston, TX (usa)
Distribution: MEPIS, Debian, Knoppix,
Posts: 4,727
Blog Entries: 15

Rep: Reputation: 234Reputation: 234Reputation: 234
I think this will do the trick for you, unless your Cygwin doesn't have sed or, possibly, GNU sed:
Code:
$ echo " 1234567890 " | sed -r ':L;s=\b([0-9]+)([0-9]{3})\b=\1,\2=g;t L'
 1,234,567,890
Thank you for the interesting Q -- I got me to look at & use sed labels & loops for the 1st time.

Anticipating your Q's:
http://www.gnu.org/software/sed/manual/sed.html
":L": http://www.gnu.org/software/sed/manu...mming-Commands
"-r": http://www.gnu.org/software/sed/manu...02dextended-30
"\b": http://www.gnu.org/software/sed/manual/sed.html#Escapes
"=": http://www.gnu.org/software/sed/manu...s_0022-Command (para 1)

(Cheshire Cat imitation)
 
1 members found this post helpful.
Old 09-25-2008, 11:22 AM   #10
KClaisse
LQ Newbie
 
Registered: Jul 2007
Posts: 7

Original Poster
Rep: Reputation: 0
Bravo sir, that works perfectly. It will take me a while to wrap my head around though . Thank you very much.
 
Old 09-27-2008, 05:42 AM   #11
archtoad6
Senior Member
 
Registered: Oct 2004
Location: Houston, TX (usa)
Distribution: MEPIS, Debian, Knoppix,
Posts: 4,727
Blog Entries: 15

Rep: Reputation: 234Reputation: 234Reputation: 234
You're welcome.

As to "wrapping your head around it", I figured it might be unfamiliar which is why I gave all the links. I'll be happy to answer any specific Q's.
 
Old 02-23-2011, 08:36 PM   #12
turtlegeek
LQ Newbie
 
Registered: Feb 2011
Location: Georgia, USA
Distribution: xubuntu, Mac OS X
Posts: 5

Rep: Reputation: 16
Smile The above did not work on my PowerMac running Tiger 10.4.11,

So I spent a few minutes to find the solution below. Since my Mac only allows Basic Regular Expression (BRE), I had to change a few things and add a few backslashes to escape the control characters:
Code:
echo "1234567890" | \
sed -e ': L
s/\([0-9]\{1,19\}\)\([0-9]\{3\}\)/\1,\2/
t L'
Note that the backslash on the first line must immediately precede a newline
and the limit of 19 for the first RE can be changed to the maximum number of
digits you may encounter. I haven't tried this on ubuntu yet but it should
work for any system that accepts BRE's (and has sed).

To see how the command works, remove the branch (t) command. You'll see that
the first iteration puts the last (rightmost) comma in. Each successive
loop matches the left portion of the number without commas. The last loop
exits because there's nothing left to match.

Last edited by turtlegeek; 02-27-2011 at 04:12 PM.
 
Old 02-24-2011, 04:24 AM   #13
Reuti
Senior Member
 
Registered: Dec 2004
Location: Marburg, Germany
Distribution: openSUSE 15.2
Posts: 1,339

Rep: Reputation: 260Reputation: 260Reputation: 260
Quote:
Originally Posted by turtlegeek View Post
So I spent a few minutes to find the solution below. Since my Mac only allows Basic Regular Expression (BRE)...
In such cases I sometimes download the GNU version and compile it on the Mac. Several commands have slight variations in the GNU version.
 
Old 02-24-2011, 08:14 AM   #14
archtoad6
Senior Member
 
Registered: Oct 2004
Location: Houston, TX (usa)
Distribution: MEPIS, Debian, Knoppix,
Posts: 4,727
Blog Entries: 15

Rep: Reputation: 234Reputation: 234Reputation: 234
turtlegeek,

Welcome to LQ -- good 1st post.
  1. Thanks for the translation to "BRE". If nothing else, you show why it is important to some of us to seek out a ver. of sed that has the "-r" option available. (Thanks, Reuti.)
  2. Technically, it's not that your Mac doesn't have "extended regular expressions", it's the ver. of sed which it supplies.
  3. Please look into & use [code] blocks. BTW, if you like, you can edit your post to add them.
  4. Good use of the backslash & separate lines. It's clearer that way.
  5. I re-ran & re-tested my orig. code & I find that the spaces in the input string & the '\b'-s used to find & clear them were unnecessary.
  6. In GNU sed the "-e" is unnecessary.
  7. Unless your ver. of sed doesn't allow it, your sed expression would be clearer if you used "s=...=...=", instead of "s/.../.../". -- Given the number of backslashes necessary to convert to BRE, it becomes a "kung fu regex"
  8. I assume that your sed doesn't allow "[0-9]+", so you used [0-9]{1,19}. BTW, it could have been "[0-9]{4,19}".
  9. My "g" option is unnecessary.
  10. Good point about the backslash on the first line.
  11. Great explanation of how it works.
Thanks for bringing this back to my attention, I had almost as much fun reviewing & rethinking it as I did originally.


Reuti,

Thanks for your suggestion.

My tested updated ver.:
Code:
echo "1234567890"  | \
sed -r '
  :L
  s=([0-9]+)([0-9]{3})=\1,\2=
  t L'

Last edited by archtoad6; 02-24-2011 at 08:19 AM.
 
1 members found this post helpful.
Old 02-24-2011, 08:16 AM   #15
archtoad6
Senior Member
 
Registered: Oct 2004
Location: Houston, TX (usa)
Distribution: MEPIS, Debian, Knoppix,
Posts: 4,727
Blog Entries: 15

Rep: Reputation: 234Reputation: 234Reputation: 234
acc-dupe trying to edit.

Last edited by archtoad6; 02-24-2011 at 08:20 AM.
 
  


Reply

Tags
sed



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Format large numbers with commas at every thousandth decimal spot helpmhost Linux - General 8 10-01-2007 11:54 AM
Bash + How to add Hexadecimal numbers trscookie Programming 7 09-03-2007 04:22 PM
[BASH] Search for 5-digit numbers in document General Programming 2 01-10-2007 08:06 PM
Decimal numbers in bash script variables? Massif Programming 3 11-07-2005 09:01 PM
fstab file format - numbers at the end jjisnow Linux - Newbie 3 03-23-2004 06:54 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 05:31 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration