LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (http://www.linuxquestions.org/questions/programming-9/)
-   -   Format numbers using bash? (http://www.linuxquestions.org/questions/programming-9/format-numbers-using-bash-672031/)

KClaisse 09-24-2008 07:11 AM

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?

ChrisAbela 09-24-2008 07:50 AM

num=12345
echo "${num%???},${num#??}"

ghostdog74 09-24-2008 08:22 AM

Quote:

Originally Posted by ChrisAbela (Post 3290210)
num=12345
echo "${num%???},${num#??}"

this is not enough. num may not be 12345 everytime.

theYinYeti 09-24-2008 08:25 AM

What exactly are you trying to achieve? How should 12345678 be rendered?

Yves.

ghostdog74 09-24-2008 08:26 AM

Quote:

Originally Posted by KClaisse (Post 3290180)
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


theYinYeti 09-24-2008 08:35 AM

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.

chrism01 09-24-2008 08:41 AM

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

KClaisse 09-25-2008 03:05 AM

Quote:

Originally Posted by chrism01 (Post 3290272)
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.

archtoad6 09-25-2008 09:29 AM

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)

:D :D :D (Cheshire Cat imitation)

KClaisse 09-25-2008 12:22 PM

Bravo sir, that works perfectly. It will take me a while to wrap my head around though :p. Thank you very much.

archtoad6 09-27-2008 06:42 AM

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.

turtlegeek 02-23-2011 09:36 PM

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.

Reuti 02-24-2011 05:24 AM

Quote:

Originally Posted by turtlegeek (Post 4269148)
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.

archtoad6 02-24-2011 09:14 AM

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'


archtoad6 02-24-2011 09:16 AM

acc-dupe trying to edit.


All times are GMT -5. The time now is 05:58 PM.