Results 1 to 7 of 7
Below is my script, my question is in three comment lines in the function? If you know how I can pull this off please let me know. Thanks.
Code:
#! ...
Enjoy an ad free experience by logging in. Not a member yet? Register.
- 01-07-2013 #1Linux Newbie
- Join Date
- Dec 2010
- Posts
- 110
sperating a number by threes
Below is my script, my question is in three comment lines in the function? If you know how I can pull this off please let me know. Thanks.
Code:#! /bin/bash # Program to take user input number and return it as a sentence. # Get user input read -p "Enter a number no higher than the billions range" NUM NUMBEROFDIGITS=${#NUM} ################################### ### FUNCTION-FindNumberOfGroups ### ################################### FindNumberOfGroups() { if [[ `expr ${NUMBEROFDIGITS} % 3` -eq 0 ]]; then # line is good for determining if there is an odd number of digits when dividing by 3 NUMBEROFGROUPS=$( expr ${NUMBEROFDIGITS} / 3 ) echo ${NUMBEROFGROUPS} else echo "remainder" NUMBEROFGROUPS=$( expr ${NUMBEROFDIGITS} / 3 ) let NUMBEROFGROUPS=NUMBEROFGROUPS+1 echo ${NUMBEROFGROUPS} # here I need to seperate NUMBEROFDIGITS divided by 3 from it's remainder # if the number is 4500 I need to seperate the number into two groups and add two leading zeros to the left number, e.g. 004 500 # if the number is 61382 I need to seperate the number into two groups and add one leading zero to the left number, e.g. 061 382 fi } #################### ### END FUNCTION ### #################### FindNumberOfGroups
- 01-07-2013 #2
printf has the capability to insert a thousand separator.
Caution: The char depends on LC_LOCALE, so it is not always a dot. (But one can set LC_LOCALE before calling printf)
The idea is:
printf outputs a separated version of a decimal number, which can then be further processed to e.g. replace the dot with a white space.
Now, the requirement of padding the leading group with zeros is a bit evil.
Because one needs to know the length of the printed decimal beforehand, and the dots (if any) also take a place.
Hence the case statement.
Code:#!/usr/bin/env bash NUM=12345678901234 let MOD=${#NUM}%3 let GRPS=${#NUM}/3 case $MOD in 1) let LENGTH=${#NUM}+2+$GRPS;; 2) let LENGTH=${#NUM}+1+$GRPS;; *) let LENGTH=${#NUM}+$GRPS-1;; esac # zero padded, dot separated number assigned to a variable a=$(printf "%'0*d\n" $LENGTH $NUM) echo $a # If there wouldnt be a requirement for leading zeros, it is easier. # No need for $LENGTH printf "%'d\n" $NUMYou must always face the curtain with a bow.
- 01-07-2013 #3Linux Engineer
- Join Date
- Apr 2006
- Location
- Saint Paul, MN, USA / CentOS, Debian, Solaris, SuSE
- Posts
- 1,199
Leading zeros
Hi.
Not tested, thought experiment: perhaps look at reminder (%) of division of length by 3, print that number of leading zeros ("...0*d ...", ... remainder) ... cheers, drlWelcome - get the most out of the forum by reading forum basics and guidelines: click here.
90% of questions can be answered by using man pages, Quick Search, Advanced Search, Google search, Wikipedia.
We look forward to helping you with the challenge of the other 10%.
( Mn, 2.6.n, AMD-64 3000+, ASUS A8V Deluxe, 1 GB, SATA + IDE, Matrox G400 AGP )
- 01-07-2013 #4Linux Newbie
- Join Date
- Nov 2012
- Posts
- 134
let's make it look a bit more "bashy"
i've been tediousCode:#!/bin/bash number=12345678901234 (( modulo=${#number}%3 , periods=${#number}/3 )) (( modulo == 1 ? (length=${#number}+periods+2) : modulo == 2 ? (length=${#number}+periods+1) : (length=${#number}+periods-1) )) printf "%'0*d\n" $length $number printf "%'d\n" $numberCode:var=$1 v=${#var} for ((i=v; i>=0; i--)) do t=${var:$i} ((${#t}>=3)) && { var=${var%$t*}; ar=( $t ${ar[@]} ); t="";} done printf -vval '%.3d ' $t ${ar[@]} echo $val
- 01-07-2013 #5
Ok, you know bash

- The code iterates backwards and number by number over $var.
- $t is assigned the part between the current position and the end of $var
- Once the length of $t is three, $t is cut from $var and also an array is build.
- So after the loop, there is a nice array of 3-digit numbers and (possibly) a one or two digit number in $t
- the printf assigns $val with a formated $t and all elements of ${ar[@]}
I didnt know about the -v VAL option. Thanks.Last edited by Irithori; 01-07-2013 at 10:43 PM.
You must always face the curtain with a bow.
- 01-08-2013 #6Linux User
- Join Date
- Jan 2005
- Location
- Saint Paul, MN
- Posts
- 396
Assuming this is not an assignement, here is an example in "bash" (rather than sh or ksh).
Which produces an output of:Code:FindNumberOfGroups() { local index local padding_string="000" local num="${1}" local len_mod_3=$((${#num} % 3)) if [ "${len_mod_3}" != "0" ] ; then num="${padding_string:0:$((3 - ${len_mod_3}))}${num}" len_mod_3=$((${#num} % 3)) fi group_cnt=$((${#num} / 3)) #for index in $(seq 0 3 ${len_of_num}); do for index in $(seq 0 3 ${#num}); do [ $index -ne 0 ] && printf " " printf "${num:${index}:3}" done printf "\n" }
Code:bash$ FindNumberOfGroups 123456789 123 456 789 bash$ echo bash$ FindNumberOfGroups 12345678 012 345 678 bash$ echo bash$ FindNumberOfGroups 1234567 001 234 567 bash$ echo bash$ FindNumberOfGroups 123 123 bash$ echo bash$ FindNumberOfGroups 12 012 bash$ echo bash$ FindNumberOfGroups 1 001 bash$
Last edited by alf55; 01-08-2013 at 06:11 AM. Reason: Corrected code (commented out bad line. Thanks watael
- 01-08-2013 #7Linux Newbie
- Join Date
- Nov 2012
- Posts
- 134
you forgot to define `$len_of_num` to `seq', it should be ${#num}


2Likes


