Find the answer to your Linux question:
Results 1 to 7 of 7
Like Tree2Likes
  • 1 Post By Irithori
  • 1 Post By watael
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.
  1. #1
    Linux Newbie
    Join Date
    Dec 2010
    Posts
    122

    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

  2. #2
    Trusted Penguin Irithori's Avatar
    Join Date
    May 2009
    Location
    Munich
    Posts
    3,423
    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" $NUM
    watael likes this.
    You must always face the curtain with a bow.

  3. #3
    drl
    drl is offline
    Linux Engineer drl's Avatar
    Join Date
    Apr 2006
    Location
    Saint Paul, MN, USA / CentOS, Debian, Slackware, {Free, Open, Net}BSD, Solaris
    Posts
    1,303

    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, drl
    Welcome - 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 )

  4. $spacer_open
    $spacer_close
  5. #4
    Linux Newbie
    Join Date
    Nov 2012
    Posts
    232
    let's make it look a bit more "bashy"
    Code:
    #!/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" $number
    i've been tedious
    Code:
    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
    Irithori likes this.

  6. #5
    Trusted Penguin Irithori's Avatar
    Join Date
    May 2009
    Location
    Munich
    Posts
    3,423
    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 11:43 PM.
    You must always face the curtain with a bow.

  7. #6
    Linux Enthusiast
    Join Date
    Jan 2005
    Location
    Saint Paul, MN
    Posts
    668
    Quote Originally Posted by Garrett85 View Post
    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
    Assuming this is not an assignement, here is an example in "bash" (rather than sh or ksh).
    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"
    }
    Which produces an output of:
    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 07:11 AM. Reason: Corrected code (commented out bad line. Thanks watael

  8. #7
    Linux Newbie
    Join Date
    Nov 2012
    Posts
    232
    you forgot to define `$len_of_num` to `seq', it should be ${#num}

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •