(Bash) Editing contents of array from within function

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
4
down vote

favorite












I'm trying to pad all the items of an array to 20 characters with whitespace, but can't seem to get my loop to work properly. It appears to increment through the array items correctly, but does not alter the items. Where am I going wrong here?



#!/bin/bash

testArray=( "bish" "bash" "bosh")

padLine ()
array=( "$@" )
testLength=20
counter=0

##loop begins here##
for i in "$array[@]";
do
size=$#array[$counter]
testLength=20

#echo ""
#echo "size: " $size
#echo "Tlength: " $testLength
#echo "count: " $array[$counter]
#echo ""

if [ $size -lt $testLength ]
then
offset=$( expr $testLength - $size )

#echo "Offset: " $offset

case $offset in
0)
l0=""
;;
1)
l1=" "
array[$counter]=$array[$counter]/%/$l1;;
2)
l2=" "
array[$counter]="$array[$counter]/%/$l2";;
3)
l3=" "
array[$counter]=$array[$counter]/%/$l3;;
4)
l4=" "
array[$counter]="$array[$counter]/%/$l4";;
5)
l5=" "
array[$counter]="$array[$counter]/%/$l5";;
6)
l6=" "
array[$counter]=$array[$counter]/%/$l6;;
7)
l7=" "
array[$counter]=$array[$counter]/%/$l7;;
8)
l8=" "
array[$counter]=$array[$counter]/%/$l8;;
9)
l9=" "
array[$counter]=$array[$counter]/%/$l9;;
10)
l10=" "
array[$counter]=$array[$counter]/%/$l10;;
11)
l11=" "
array[$counter]=$array[$counter]/%/$l11;;
12)
l12=" "
array[$counter]=$array[$counter]/%/$l12;;
13)
l13=" "
array[$counter]=$array[$counter]/%/$l13;;
14)
l14=" "
array[$counter]=$array[$counter]/%/$l14;;
15)
l15=" "
array[$counter]=$array[$counter]/%/$l15;;
16)
l16=" "
array[$counter]=$array[$counter]/%/$l16;;
17)
l17=" "
array[$counter]=$array[$counter]/%/$l17;;
18)
l18=" "
array[$counter]=$array[$counter]/%/$l18;;
19)
l19=" "
array[$counter]=$array[$counter]/%/$l19;;

*)
esac
fi
counter=$( expr $counter + 1 )
done


padLine "$testArray[@]"


echo -e "$testArray[0]"
echo -e "$testArray[1]"
echo -e "$testArray[2]"


Expected output:



bish #lines end here, padded to 20 chars
bash #
bosh #


Actual output:



bish# no padding
bash
bosh






share|improve this question























    up vote
    4
    down vote

    favorite












    I'm trying to pad all the items of an array to 20 characters with whitespace, but can't seem to get my loop to work properly. It appears to increment through the array items correctly, but does not alter the items. Where am I going wrong here?



    #!/bin/bash

    testArray=( "bish" "bash" "bosh")

    padLine ()
    array=( "$@" )
    testLength=20
    counter=0

    ##loop begins here##
    for i in "$array[@]";
    do
    size=$#array[$counter]
    testLength=20

    #echo ""
    #echo "size: " $size
    #echo "Tlength: " $testLength
    #echo "count: " $array[$counter]
    #echo ""

    if [ $size -lt $testLength ]
    then
    offset=$( expr $testLength - $size )

    #echo "Offset: " $offset

    case $offset in
    0)
    l0=""
    ;;
    1)
    l1=" "
    array[$counter]=$array[$counter]/%/$l1;;
    2)
    l2=" "
    array[$counter]="$array[$counter]/%/$l2";;
    3)
    l3=" "
    array[$counter]=$array[$counter]/%/$l3;;
    4)
    l4=" "
    array[$counter]="$array[$counter]/%/$l4";;
    5)
    l5=" "
    array[$counter]="$array[$counter]/%/$l5";;
    6)
    l6=" "
    array[$counter]=$array[$counter]/%/$l6;;
    7)
    l7=" "
    array[$counter]=$array[$counter]/%/$l7;;
    8)
    l8=" "
    array[$counter]=$array[$counter]/%/$l8;;
    9)
    l9=" "
    array[$counter]=$array[$counter]/%/$l9;;
    10)
    l10=" "
    array[$counter]=$array[$counter]/%/$l10;;
    11)
    l11=" "
    array[$counter]=$array[$counter]/%/$l11;;
    12)
    l12=" "
    array[$counter]=$array[$counter]/%/$l12;;
    13)
    l13=" "
    array[$counter]=$array[$counter]/%/$l13;;
    14)
    l14=" "
    array[$counter]=$array[$counter]/%/$l14;;
    15)
    l15=" "
    array[$counter]=$array[$counter]/%/$l15;;
    16)
    l16=" "
    array[$counter]=$array[$counter]/%/$l16;;
    17)
    l17=" "
    array[$counter]=$array[$counter]/%/$l17;;
    18)
    l18=" "
    array[$counter]=$array[$counter]/%/$l18;;
    19)
    l19=" "
    array[$counter]=$array[$counter]/%/$l19;;

    *)
    esac
    fi
    counter=$( expr $counter + 1 )
    done


    padLine "$testArray[@]"


    echo -e "$testArray[0]"
    echo -e "$testArray[1]"
    echo -e "$testArray[2]"


    Expected output:



    bish #lines end here, padded to 20 chars
    bash #
    bosh #


    Actual output:



    bish# no padding
    bash
    bosh






    share|improve this question





















      up vote
      4
      down vote

      favorite









      up vote
      4
      down vote

      favorite











      I'm trying to pad all the items of an array to 20 characters with whitespace, but can't seem to get my loop to work properly. It appears to increment through the array items correctly, but does not alter the items. Where am I going wrong here?



      #!/bin/bash

      testArray=( "bish" "bash" "bosh")

      padLine ()
      array=( "$@" )
      testLength=20
      counter=0

      ##loop begins here##
      for i in "$array[@]";
      do
      size=$#array[$counter]
      testLength=20

      #echo ""
      #echo "size: " $size
      #echo "Tlength: " $testLength
      #echo "count: " $array[$counter]
      #echo ""

      if [ $size -lt $testLength ]
      then
      offset=$( expr $testLength - $size )

      #echo "Offset: " $offset

      case $offset in
      0)
      l0=""
      ;;
      1)
      l1=" "
      array[$counter]=$array[$counter]/%/$l1;;
      2)
      l2=" "
      array[$counter]="$array[$counter]/%/$l2";;
      3)
      l3=" "
      array[$counter]=$array[$counter]/%/$l3;;
      4)
      l4=" "
      array[$counter]="$array[$counter]/%/$l4";;
      5)
      l5=" "
      array[$counter]="$array[$counter]/%/$l5";;
      6)
      l6=" "
      array[$counter]=$array[$counter]/%/$l6;;
      7)
      l7=" "
      array[$counter]=$array[$counter]/%/$l7;;
      8)
      l8=" "
      array[$counter]=$array[$counter]/%/$l8;;
      9)
      l9=" "
      array[$counter]=$array[$counter]/%/$l9;;
      10)
      l10=" "
      array[$counter]=$array[$counter]/%/$l10;;
      11)
      l11=" "
      array[$counter]=$array[$counter]/%/$l11;;
      12)
      l12=" "
      array[$counter]=$array[$counter]/%/$l12;;
      13)
      l13=" "
      array[$counter]=$array[$counter]/%/$l13;;
      14)
      l14=" "
      array[$counter]=$array[$counter]/%/$l14;;
      15)
      l15=" "
      array[$counter]=$array[$counter]/%/$l15;;
      16)
      l16=" "
      array[$counter]=$array[$counter]/%/$l16;;
      17)
      l17=" "
      array[$counter]=$array[$counter]/%/$l17;;
      18)
      l18=" "
      array[$counter]=$array[$counter]/%/$l18;;
      19)
      l19=" "
      array[$counter]=$array[$counter]/%/$l19;;

      *)
      esac
      fi
      counter=$( expr $counter + 1 )
      done


      padLine "$testArray[@]"


      echo -e "$testArray[0]"
      echo -e "$testArray[1]"
      echo -e "$testArray[2]"


      Expected output:



      bish #lines end here, padded to 20 chars
      bash #
      bosh #


      Actual output:



      bish# no padding
      bash
      bosh






      share|improve this question











      I'm trying to pad all the items of an array to 20 characters with whitespace, but can't seem to get my loop to work properly. It appears to increment through the array items correctly, but does not alter the items. Where am I going wrong here?



      #!/bin/bash

      testArray=( "bish" "bash" "bosh")

      padLine ()
      array=( "$@" )
      testLength=20
      counter=0

      ##loop begins here##
      for i in "$array[@]";
      do
      size=$#array[$counter]
      testLength=20

      #echo ""
      #echo "size: " $size
      #echo "Tlength: " $testLength
      #echo "count: " $array[$counter]
      #echo ""

      if [ $size -lt $testLength ]
      then
      offset=$( expr $testLength - $size )

      #echo "Offset: " $offset

      case $offset in
      0)
      l0=""
      ;;
      1)
      l1=" "
      array[$counter]=$array[$counter]/%/$l1;;
      2)
      l2=" "
      array[$counter]="$array[$counter]/%/$l2";;
      3)
      l3=" "
      array[$counter]=$array[$counter]/%/$l3;;
      4)
      l4=" "
      array[$counter]="$array[$counter]/%/$l4";;
      5)
      l5=" "
      array[$counter]="$array[$counter]/%/$l5";;
      6)
      l6=" "
      array[$counter]=$array[$counter]/%/$l6;;
      7)
      l7=" "
      array[$counter]=$array[$counter]/%/$l7;;
      8)
      l8=" "
      array[$counter]=$array[$counter]/%/$l8;;
      9)
      l9=" "
      array[$counter]=$array[$counter]/%/$l9;;
      10)
      l10=" "
      array[$counter]=$array[$counter]/%/$l10;;
      11)
      l11=" "
      array[$counter]=$array[$counter]/%/$l11;;
      12)
      l12=" "
      array[$counter]=$array[$counter]/%/$l12;;
      13)
      l13=" "
      array[$counter]=$array[$counter]/%/$l13;;
      14)
      l14=" "
      array[$counter]=$array[$counter]/%/$l14;;
      15)
      l15=" "
      array[$counter]=$array[$counter]/%/$l15;;
      16)
      l16=" "
      array[$counter]=$array[$counter]/%/$l16;;
      17)
      l17=" "
      array[$counter]=$array[$counter]/%/$l17;;
      18)
      l18=" "
      array[$counter]=$array[$counter]/%/$l18;;
      19)
      l19=" "
      array[$counter]=$array[$counter]/%/$l19;;

      *)
      esac
      fi
      counter=$( expr $counter + 1 )
      done


      padLine "$testArray[@]"


      echo -e "$testArray[0]"
      echo -e "$testArray[1]"
      echo -e "$testArray[2]"


      Expected output:



      bish #lines end here, padded to 20 chars
      bash #
      bosh #


      Actual output:



      bish# no padding
      bash
      bosh








      share|improve this question










      share|improve this question




      share|improve this question









      asked Jun 13 at 12:26









      user19923311885

      211




      211




















          6 Answers
          6






          active

          oldest

          votes

















          up vote
          6
          down vote













          Just for output:



          array=( bish bash bosh )
          printf '%-20s#n' "$array[@]"


          This would produce



          bish #
          bash #
          bosh #


          ... where # occurs in column 21.



          To make a new array (and printing it):



          array=( bish bash bosh )

          for elem in "$array[@]"; do
          padarr+=( "$( printf '%-20s#' "$elem" )" )
          done

          printf '%sn' "$padarr[@]"


          With /bin/sh, just printing:



          set -- bish bash bosh
          printf '%-20s#n' "$@"


          With /bin/sh, modifying $@ in-place:



          set -- bish bash bosh
          i=0
          while [ "$i" -lt "$#" ]; do
          set -- "$@" "$( printf '%-20s#' "$1" )"
          shift
          i=$(( i + 1 ))
          done

          printf '%sn' "$@"


          The printf formatting string %-20s reserves 20 characters for a left-justified string.




          As a bash (4.3+) function:



          pad_array () 
          local padlen=$1
          local -n localarray=$2

          local -a tmp
          local elem

          for elem in "$localarray[@]"; do
          tmp+=( "$( printf '%-*s#' "$padlen" "$elem" )" )
          done

          localarray=( "$tmp[@]" )


          myarray=( bish bash bosh )
          pad_array 20 myarray

          printf '%sn' "$myarray[@]"


          The pad_array function here additionally allows you to choose the amount of padding.



          The array is passed by its name and is received by the function in a name reference variable. This means that whenever the name reference is accessed in the function, the named variable are actually used.






          share|improve this answer



















          • 2




            Note that printf %-20s pads to 20 bytes, not characters in bash which would make a different for multi-byte characters. See also printf -v in bash to avoid the cmdsubst.
            – Stéphane Chazelas
            Jun 13 at 13:08











          • Note that the nameref variant could change the indices of the array. An array defined as a([5]=x [12]=y) would end up as a([0]="x ..." [1]="y ...")
            – Stéphane Chazelas
            Jun 13 at 13:43


















          up vote
          4
          down vote













          If switching to zsh is an option:



          $ array=(foo bar bàz '')
          $ padded_array=($(r:20:)array)
          $ printf '<%s>n' $padded_array
          <foo >
          <bar >
          <bàz >
          < >


          Note that that (r:20:) right-padding parameter expansion flag pads but also truncates to 20 characters for strings that are longer.



          Another option with zsh is to do:



          padded_array=()
          (($#array)) && printf -v padded_array '%-20s' "$array[@]"


          Contrary to bash, the padding is done character-wise as opposed to byte-wise and zsh supports array arguments to the -v option.



          Note that if $array contains just one element, $padded_array is converted to scalar.



          For padding+truncating, replace %-20s with %-20.20s.






          share|improve this answer






























            up vote
            1
            down vote













            You're doing two mistakes.



            1. You're passing testArray to the function, then you create the new array in the function, you modify it, but you finally print out the first array. You want to print the modified results, right?



            2. Your script doesn't do what you expect, because you use this construct:



               array[$counter]=$array[$counter]/%/$l16


              This is the pattern substitution of general form $parameter/pattern/string. You don't need to substitute anything. You have the suffix ready at this point, just need to append it like:



              array[$counter]="$array[$counter]$l16"


            You can access the array array outside of the function, as the array is not declared as local. So you can just use:



            echo -e "$array[0]"


            etc.






            share|improve this answer




























              up vote
              1
              down vote













              To pass variables by reference in bash 4.3+, you can use typeset -n:



              pad_array() 
              typeset -n _array="$1"
              typeset _n="$2" _pad _i
              printf -v _pad '%*s' "$_n"

              for _i in "$!_array[@]"; do
              (($#_array[_i] < _n))

              array=(foo b bàz '')
              pad_array array 20


              The typeset -n nameref feature comes from ksh93 however note that contrary to in ksh93, the above won't work to pad array variables whose name is used in the function (hence the underscore prefix for them to limit the risk of clashing).






              share|improve this answer






























                up vote
                0
                down vote













                If you’re willing to place an arbitrary upper limit
                on the number of spaces to add
                (and you obviously are,
                as your case statement can’t handle a length greater than 20),
                and you’re just talking about bytes
                (and not characters, which can be multi-byte),
                a simple way to pad a variable to a given length is:



                # 75 spaces
                spaces=" "
                ︙
                length=20
                ︙
                newValue=$(expr substr "$value$spaces" 1 "$length")





                share|improve this answer






























                  up vote
                  0
                  down vote













                  Core idea



                  for elem in "$localarrayname[@]"; do
                  localtoarray+=( "$(printf '<%-*.*s>n' "$p" "$p" "$elem")" )
                  done


                  Simple var



                  Using printf to add a variable count of spaces is very simple (the asterisk is the count):



                  $ printf '<%-*s>' 8 hello ; echo
                  <hello >


                  It could even be used to either extend or cut an string to a count:



                  $ printf '<%-*.*s>' 8 8 "TestingHello" ; echo
                  <TestingH>


                  Fixed trailing string



                  Using variable substitution we can add a fixed string to a variable:



                  $ var=hello
                  $ printf '<%s>n' "$var/%/"xxx""
                  <helloxxx>


                  That could be expanded to an array of values:



                  $ var=( hello world test )
                  $ printf '<%s>n' "$var[@]/%/"xxx""
                  <helloxxx>
                  <worldxxx>
                  <testxxx>


                  Array of values.



                  However, to add a variable count of spaces to an array we need to use a loop.

                  We can use a function to pass the list of values (only printing):



                  padarray() p=$1; shift
                  for elem; do
                  printf '<%-*.*s>n' "$p" "$p" "$elem"
                  done


                  array=( foo qux quuux alongerstring )
                  padarray 15 "$array[@]"


                  It prints:



                  $ ./script
                  <foo >
                  <qux >
                  <quuux >
                  <alongerstringto>


                  Indirect array.



                  To pass the arguments to a new array using the array(s) names (indirect):



                  padarray() local p=$1;
                  local -n localarrayname=$2 localtoarray=$3
                  localtoarray=()
                  for elem in "$localarrayname[@]"; do
                  localtoarray+=( "$(printf '<%-*.*s>n' "$p" "$p" "$elem")" )
                  done


                  array=( foo qux quuux alongerstringtotest )
                  padarray 12 array paddedarray
                  printf '%sn' "$paddedarray[@]"


                  Which on execution prints a similar result:



                  $ ./script
                  <foo >
                  <qux >
                  <quuux >
                  <alongerstrin>


                  Better pad count.



                  Adding a more robust count number of padding characters ($p):



                  p=$1//[!0-9] # Select only numeric digits.
                  (( 0<=p && p<=999 )) && return 2 # Return on error. Count out of range.


                  Final



                  We end with this script:



                  #!/bin/bash

                  padarray()


                  array=( bash bish bosh "" foo qux quuux "A Longer String To Test" )
                  padarray 20 array paddedarray
                  printf '%sn' "$paddedarray[@]"





                  share|improve this answer





















                    Your Answer







                    StackExchange.ready(function()
                    var channelOptions =
                    tags: "".split(" "),
                    id: "106"
                    ;
                    initTagRenderer("".split(" "), "".split(" "), channelOptions);

                    StackExchange.using("externalEditor", function()
                    // Have to fire editor after snippets, if snippets enabled
                    if (StackExchange.settings.snippets.snippetsEnabled)
                    StackExchange.using("snippets", function()
                    createEditor();
                    );

                    else
                    createEditor();

                    );

                    function createEditor()
                    StackExchange.prepareEditor(
                    heartbeatType: 'answer',
                    convertImagesToLinks: false,
                    noModals: false,
                    showLowRepImageUploadWarning: true,
                    reputationToPostImages: null,
                    bindNavPrevention: true,
                    postfix: "",
                    onDemand: true,
                    discardSelector: ".discard-answer"
                    ,immediatelyShowMarkdownHelp:true
                    );



                    );








                     

                    draft saved


                    draft discarded


















                    StackExchange.ready(
                    function ()
                    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f449535%2fbash-editing-contents-of-array-from-within-function%23new-answer', 'question_page');

                    );

                    Post as a guest






























                    6 Answers
                    6






                    active

                    oldest

                    votes








                    6 Answers
                    6






                    active

                    oldest

                    votes









                    active

                    oldest

                    votes






                    active

                    oldest

                    votes








                    up vote
                    6
                    down vote













                    Just for output:



                    array=( bish bash bosh )
                    printf '%-20s#n' "$array[@]"


                    This would produce



                    bish #
                    bash #
                    bosh #


                    ... where # occurs in column 21.



                    To make a new array (and printing it):



                    array=( bish bash bosh )

                    for elem in "$array[@]"; do
                    padarr+=( "$( printf '%-20s#' "$elem" )" )
                    done

                    printf '%sn' "$padarr[@]"


                    With /bin/sh, just printing:



                    set -- bish bash bosh
                    printf '%-20s#n' "$@"


                    With /bin/sh, modifying $@ in-place:



                    set -- bish bash bosh
                    i=0
                    while [ "$i" -lt "$#" ]; do
                    set -- "$@" "$( printf '%-20s#' "$1" )"
                    shift
                    i=$(( i + 1 ))
                    done

                    printf '%sn' "$@"


                    The printf formatting string %-20s reserves 20 characters for a left-justified string.




                    As a bash (4.3+) function:



                    pad_array () 
                    local padlen=$1
                    local -n localarray=$2

                    local -a tmp
                    local elem

                    for elem in "$localarray[@]"; do
                    tmp+=( "$( printf '%-*s#' "$padlen" "$elem" )" )
                    done

                    localarray=( "$tmp[@]" )


                    myarray=( bish bash bosh )
                    pad_array 20 myarray

                    printf '%sn' "$myarray[@]"


                    The pad_array function here additionally allows you to choose the amount of padding.



                    The array is passed by its name and is received by the function in a name reference variable. This means that whenever the name reference is accessed in the function, the named variable are actually used.






                    share|improve this answer



















                    • 2




                      Note that printf %-20s pads to 20 bytes, not characters in bash which would make a different for multi-byte characters. See also printf -v in bash to avoid the cmdsubst.
                      – Stéphane Chazelas
                      Jun 13 at 13:08











                    • Note that the nameref variant could change the indices of the array. An array defined as a([5]=x [12]=y) would end up as a([0]="x ..." [1]="y ...")
                      – Stéphane Chazelas
                      Jun 13 at 13:43















                    up vote
                    6
                    down vote













                    Just for output:



                    array=( bish bash bosh )
                    printf '%-20s#n' "$array[@]"


                    This would produce



                    bish #
                    bash #
                    bosh #


                    ... where # occurs in column 21.



                    To make a new array (and printing it):



                    array=( bish bash bosh )

                    for elem in "$array[@]"; do
                    padarr+=( "$( printf '%-20s#' "$elem" )" )
                    done

                    printf '%sn' "$padarr[@]"


                    With /bin/sh, just printing:



                    set -- bish bash bosh
                    printf '%-20s#n' "$@"


                    With /bin/sh, modifying $@ in-place:



                    set -- bish bash bosh
                    i=0
                    while [ "$i" -lt "$#" ]; do
                    set -- "$@" "$( printf '%-20s#' "$1" )"
                    shift
                    i=$(( i + 1 ))
                    done

                    printf '%sn' "$@"


                    The printf formatting string %-20s reserves 20 characters for a left-justified string.




                    As a bash (4.3+) function:



                    pad_array () 
                    local padlen=$1
                    local -n localarray=$2

                    local -a tmp
                    local elem

                    for elem in "$localarray[@]"; do
                    tmp+=( "$( printf '%-*s#' "$padlen" "$elem" )" )
                    done

                    localarray=( "$tmp[@]" )


                    myarray=( bish bash bosh )
                    pad_array 20 myarray

                    printf '%sn' "$myarray[@]"


                    The pad_array function here additionally allows you to choose the amount of padding.



                    The array is passed by its name and is received by the function in a name reference variable. This means that whenever the name reference is accessed in the function, the named variable are actually used.






                    share|improve this answer



















                    • 2




                      Note that printf %-20s pads to 20 bytes, not characters in bash which would make a different for multi-byte characters. See also printf -v in bash to avoid the cmdsubst.
                      – Stéphane Chazelas
                      Jun 13 at 13:08











                    • Note that the nameref variant could change the indices of the array. An array defined as a([5]=x [12]=y) would end up as a([0]="x ..." [1]="y ...")
                      – Stéphane Chazelas
                      Jun 13 at 13:43













                    up vote
                    6
                    down vote










                    up vote
                    6
                    down vote









                    Just for output:



                    array=( bish bash bosh )
                    printf '%-20s#n' "$array[@]"


                    This would produce



                    bish #
                    bash #
                    bosh #


                    ... where # occurs in column 21.



                    To make a new array (and printing it):



                    array=( bish bash bosh )

                    for elem in "$array[@]"; do
                    padarr+=( "$( printf '%-20s#' "$elem" )" )
                    done

                    printf '%sn' "$padarr[@]"


                    With /bin/sh, just printing:



                    set -- bish bash bosh
                    printf '%-20s#n' "$@"


                    With /bin/sh, modifying $@ in-place:



                    set -- bish bash bosh
                    i=0
                    while [ "$i" -lt "$#" ]; do
                    set -- "$@" "$( printf '%-20s#' "$1" )"
                    shift
                    i=$(( i + 1 ))
                    done

                    printf '%sn' "$@"


                    The printf formatting string %-20s reserves 20 characters for a left-justified string.




                    As a bash (4.3+) function:



                    pad_array () 
                    local padlen=$1
                    local -n localarray=$2

                    local -a tmp
                    local elem

                    for elem in "$localarray[@]"; do
                    tmp+=( "$( printf '%-*s#' "$padlen" "$elem" )" )
                    done

                    localarray=( "$tmp[@]" )


                    myarray=( bish bash bosh )
                    pad_array 20 myarray

                    printf '%sn' "$myarray[@]"


                    The pad_array function here additionally allows you to choose the amount of padding.



                    The array is passed by its name and is received by the function in a name reference variable. This means that whenever the name reference is accessed in the function, the named variable are actually used.






                    share|improve this answer















                    Just for output:



                    array=( bish bash bosh )
                    printf '%-20s#n' "$array[@]"


                    This would produce



                    bish #
                    bash #
                    bosh #


                    ... where # occurs in column 21.



                    To make a new array (and printing it):



                    array=( bish bash bosh )

                    for elem in "$array[@]"; do
                    padarr+=( "$( printf '%-20s#' "$elem" )" )
                    done

                    printf '%sn' "$padarr[@]"


                    With /bin/sh, just printing:



                    set -- bish bash bosh
                    printf '%-20s#n' "$@"


                    With /bin/sh, modifying $@ in-place:



                    set -- bish bash bosh
                    i=0
                    while [ "$i" -lt "$#" ]; do
                    set -- "$@" "$( printf '%-20s#' "$1" )"
                    shift
                    i=$(( i + 1 ))
                    done

                    printf '%sn' "$@"


                    The printf formatting string %-20s reserves 20 characters for a left-justified string.




                    As a bash (4.3+) function:



                    pad_array () 
                    local padlen=$1
                    local -n localarray=$2

                    local -a tmp
                    local elem

                    for elem in "$localarray[@]"; do
                    tmp+=( "$( printf '%-*s#' "$padlen" "$elem" )" )
                    done

                    localarray=( "$tmp[@]" )


                    myarray=( bish bash bosh )
                    pad_array 20 myarray

                    printf '%sn' "$myarray[@]"


                    The pad_array function here additionally allows you to choose the amount of padding.



                    The array is passed by its name and is received by the function in a name reference variable. This means that whenever the name reference is accessed in the function, the named variable are actually used.







                    share|improve this answer















                    share|improve this answer



                    share|improve this answer








                    edited Jun 13 at 12:59


























                    answered Jun 13 at 12:41









                    Kusalananda

                    101k13199312




                    101k13199312







                    • 2




                      Note that printf %-20s pads to 20 bytes, not characters in bash which would make a different for multi-byte characters. See also printf -v in bash to avoid the cmdsubst.
                      – Stéphane Chazelas
                      Jun 13 at 13:08











                    • Note that the nameref variant could change the indices of the array. An array defined as a([5]=x [12]=y) would end up as a([0]="x ..." [1]="y ...")
                      – Stéphane Chazelas
                      Jun 13 at 13:43













                    • 2




                      Note that printf %-20s pads to 20 bytes, not characters in bash which would make a different for multi-byte characters. See also printf -v in bash to avoid the cmdsubst.
                      – Stéphane Chazelas
                      Jun 13 at 13:08











                    • Note that the nameref variant could change the indices of the array. An array defined as a([5]=x [12]=y) would end up as a([0]="x ..." [1]="y ...")
                      – Stéphane Chazelas
                      Jun 13 at 13:43








                    2




                    2




                    Note that printf %-20s pads to 20 bytes, not characters in bash which would make a different for multi-byte characters. See also printf -v in bash to avoid the cmdsubst.
                    – Stéphane Chazelas
                    Jun 13 at 13:08





                    Note that printf %-20s pads to 20 bytes, not characters in bash which would make a different for multi-byte characters. See also printf -v in bash to avoid the cmdsubst.
                    – Stéphane Chazelas
                    Jun 13 at 13:08













                    Note that the nameref variant could change the indices of the array. An array defined as a([5]=x [12]=y) would end up as a([0]="x ..." [1]="y ...")
                    – Stéphane Chazelas
                    Jun 13 at 13:43





                    Note that the nameref variant could change the indices of the array. An array defined as a([5]=x [12]=y) would end up as a([0]="x ..." [1]="y ...")
                    – Stéphane Chazelas
                    Jun 13 at 13:43













                    up vote
                    4
                    down vote













                    If switching to zsh is an option:



                    $ array=(foo bar bàz '')
                    $ padded_array=($(r:20:)array)
                    $ printf '<%s>n' $padded_array
                    <foo >
                    <bar >
                    <bàz >
                    < >


                    Note that that (r:20:) right-padding parameter expansion flag pads but also truncates to 20 characters for strings that are longer.



                    Another option with zsh is to do:



                    padded_array=()
                    (($#array)) && printf -v padded_array '%-20s' "$array[@]"


                    Contrary to bash, the padding is done character-wise as opposed to byte-wise and zsh supports array arguments to the -v option.



                    Note that if $array contains just one element, $padded_array is converted to scalar.



                    For padding+truncating, replace %-20s with %-20.20s.






                    share|improve this answer



























                      up vote
                      4
                      down vote













                      If switching to zsh is an option:



                      $ array=(foo bar bàz '')
                      $ padded_array=($(r:20:)array)
                      $ printf '<%s>n' $padded_array
                      <foo >
                      <bar >
                      <bàz >
                      < >


                      Note that that (r:20:) right-padding parameter expansion flag pads but also truncates to 20 characters for strings that are longer.



                      Another option with zsh is to do:



                      padded_array=()
                      (($#array)) && printf -v padded_array '%-20s' "$array[@]"


                      Contrary to bash, the padding is done character-wise as opposed to byte-wise and zsh supports array arguments to the -v option.



                      Note that if $array contains just one element, $padded_array is converted to scalar.



                      For padding+truncating, replace %-20s with %-20.20s.






                      share|improve this answer

























                        up vote
                        4
                        down vote










                        up vote
                        4
                        down vote









                        If switching to zsh is an option:



                        $ array=(foo bar bàz '')
                        $ padded_array=($(r:20:)array)
                        $ printf '<%s>n' $padded_array
                        <foo >
                        <bar >
                        <bàz >
                        < >


                        Note that that (r:20:) right-padding parameter expansion flag pads but also truncates to 20 characters for strings that are longer.



                        Another option with zsh is to do:



                        padded_array=()
                        (($#array)) && printf -v padded_array '%-20s' "$array[@]"


                        Contrary to bash, the padding is done character-wise as opposed to byte-wise and zsh supports array arguments to the -v option.



                        Note that if $array contains just one element, $padded_array is converted to scalar.



                        For padding+truncating, replace %-20s with %-20.20s.






                        share|improve this answer















                        If switching to zsh is an option:



                        $ array=(foo bar bàz '')
                        $ padded_array=($(r:20:)array)
                        $ printf '<%s>n' $padded_array
                        <foo >
                        <bar >
                        <bàz >
                        < >


                        Note that that (r:20:) right-padding parameter expansion flag pads but also truncates to 20 characters for strings that are longer.



                        Another option with zsh is to do:



                        padded_array=()
                        (($#array)) && printf -v padded_array '%-20s' "$array[@]"


                        Contrary to bash, the padding is done character-wise as opposed to byte-wise and zsh supports array arguments to the -v option.



                        Note that if $array contains just one element, $padded_array is converted to scalar.



                        For padding+truncating, replace %-20s with %-20.20s.







                        share|improve this answer















                        share|improve this answer



                        share|improve this answer








                        edited Jun 13 at 13:19


























                        answered Jun 13 at 13:12









                        Stéphane Chazelas

                        279k53513844




                        279k53513844




















                            up vote
                            1
                            down vote













                            You're doing two mistakes.



                            1. You're passing testArray to the function, then you create the new array in the function, you modify it, but you finally print out the first array. You want to print the modified results, right?



                            2. Your script doesn't do what you expect, because you use this construct:



                               array[$counter]=$array[$counter]/%/$l16


                              This is the pattern substitution of general form $parameter/pattern/string. You don't need to substitute anything. You have the suffix ready at this point, just need to append it like:



                              array[$counter]="$array[$counter]$l16"


                            You can access the array array outside of the function, as the array is not declared as local. So you can just use:



                            echo -e "$array[0]"


                            etc.






                            share|improve this answer

























                              up vote
                              1
                              down vote













                              You're doing two mistakes.



                              1. You're passing testArray to the function, then you create the new array in the function, you modify it, but you finally print out the first array. You want to print the modified results, right?



                              2. Your script doesn't do what you expect, because you use this construct:



                                 array[$counter]=$array[$counter]/%/$l16


                                This is the pattern substitution of general form $parameter/pattern/string. You don't need to substitute anything. You have the suffix ready at this point, just need to append it like:



                                array[$counter]="$array[$counter]$l16"


                              You can access the array array outside of the function, as the array is not declared as local. So you can just use:



                              echo -e "$array[0]"


                              etc.






                              share|improve this answer























                                up vote
                                1
                                down vote










                                up vote
                                1
                                down vote









                                You're doing two mistakes.



                                1. You're passing testArray to the function, then you create the new array in the function, you modify it, but you finally print out the first array. You want to print the modified results, right?



                                2. Your script doesn't do what you expect, because you use this construct:



                                   array[$counter]=$array[$counter]/%/$l16


                                  This is the pattern substitution of general form $parameter/pattern/string. You don't need to substitute anything. You have the suffix ready at this point, just need to append it like:



                                  array[$counter]="$array[$counter]$l16"


                                You can access the array array outside of the function, as the array is not declared as local. So you can just use:



                                echo -e "$array[0]"


                                etc.






                                share|improve this answer













                                You're doing two mistakes.



                                1. You're passing testArray to the function, then you create the new array in the function, you modify it, but you finally print out the first array. You want to print the modified results, right?



                                2. Your script doesn't do what you expect, because you use this construct:



                                   array[$counter]=$array[$counter]/%/$l16


                                  This is the pattern substitution of general form $parameter/pattern/string. You don't need to substitute anything. You have the suffix ready at this point, just need to append it like:



                                  array[$counter]="$array[$counter]$l16"


                                You can access the array array outside of the function, as the array is not declared as local. So you can just use:



                                echo -e "$array[0]"


                                etc.







                                share|improve this answer













                                share|improve this answer



                                share|improve this answer











                                answered Jun 13 at 13:08









                                Tomasz

                                8,03052560




                                8,03052560




















                                    up vote
                                    1
                                    down vote













                                    To pass variables by reference in bash 4.3+, you can use typeset -n:



                                    pad_array() 
                                    typeset -n _array="$1"
                                    typeset _n="$2" _pad _i
                                    printf -v _pad '%*s' "$_n"

                                    for _i in "$!_array[@]"; do
                                    (($#_array[_i] < _n))

                                    array=(foo b bàz '')
                                    pad_array array 20


                                    The typeset -n nameref feature comes from ksh93 however note that contrary to in ksh93, the above won't work to pad array variables whose name is used in the function (hence the underscore prefix for them to limit the risk of clashing).






                                    share|improve this answer



























                                      up vote
                                      1
                                      down vote













                                      To pass variables by reference in bash 4.3+, you can use typeset -n:



                                      pad_array() 
                                      typeset -n _array="$1"
                                      typeset _n="$2" _pad _i
                                      printf -v _pad '%*s' "$_n"

                                      for _i in "$!_array[@]"; do
                                      (($#_array[_i] < _n))

                                      array=(foo b bàz '')
                                      pad_array array 20


                                      The typeset -n nameref feature comes from ksh93 however note that contrary to in ksh93, the above won't work to pad array variables whose name is used in the function (hence the underscore prefix for them to limit the risk of clashing).






                                      share|improve this answer

























                                        up vote
                                        1
                                        down vote










                                        up vote
                                        1
                                        down vote









                                        To pass variables by reference in bash 4.3+, you can use typeset -n:



                                        pad_array() 
                                        typeset -n _array="$1"
                                        typeset _n="$2" _pad _i
                                        printf -v _pad '%*s' "$_n"

                                        for _i in "$!_array[@]"; do
                                        (($#_array[_i] < _n))

                                        array=(foo b bàz '')
                                        pad_array array 20


                                        The typeset -n nameref feature comes from ksh93 however note that contrary to in ksh93, the above won't work to pad array variables whose name is used in the function (hence the underscore prefix for them to limit the risk of clashing).






                                        share|improve this answer















                                        To pass variables by reference in bash 4.3+, you can use typeset -n:



                                        pad_array() 
                                        typeset -n _array="$1"
                                        typeset _n="$2" _pad _i
                                        printf -v _pad '%*s' "$_n"

                                        for _i in "$!_array[@]"; do
                                        (($#_array[_i] < _n))

                                        array=(foo b bàz '')
                                        pad_array array 20


                                        The typeset -n nameref feature comes from ksh93 however note that contrary to in ksh93, the above won't work to pad array variables whose name is used in the function (hence the underscore prefix for them to limit the risk of clashing).







                                        share|improve this answer















                                        share|improve this answer



                                        share|improve this answer








                                        edited Jun 13 at 14:12


























                                        answered Jun 13 at 13:33









                                        Stéphane Chazelas

                                        279k53513844




                                        279k53513844




















                                            up vote
                                            0
                                            down vote













                                            If you’re willing to place an arbitrary upper limit
                                            on the number of spaces to add
                                            (and you obviously are,
                                            as your case statement can’t handle a length greater than 20),
                                            and you’re just talking about bytes
                                            (and not characters, which can be multi-byte),
                                            a simple way to pad a variable to a given length is:



                                            # 75 spaces
                                            spaces=" "
                                            ︙
                                            length=20
                                            ︙
                                            newValue=$(expr substr "$value$spaces" 1 "$length")





                                            share|improve this answer



























                                              up vote
                                              0
                                              down vote













                                              If you’re willing to place an arbitrary upper limit
                                              on the number of spaces to add
                                              (and you obviously are,
                                              as your case statement can’t handle a length greater than 20),
                                              and you’re just talking about bytes
                                              (and not characters, which can be multi-byte),
                                              a simple way to pad a variable to a given length is:



                                              # 75 spaces
                                              spaces=" "
                                              ︙
                                              length=20
                                              ︙
                                              newValue=$(expr substr "$value$spaces" 1 "$length")





                                              share|improve this answer

























                                                up vote
                                                0
                                                down vote










                                                up vote
                                                0
                                                down vote









                                                If you’re willing to place an arbitrary upper limit
                                                on the number of spaces to add
                                                (and you obviously are,
                                                as your case statement can’t handle a length greater than 20),
                                                and you’re just talking about bytes
                                                (and not characters, which can be multi-byte),
                                                a simple way to pad a variable to a given length is:



                                                # 75 spaces
                                                spaces=" "
                                                ︙
                                                length=20
                                                ︙
                                                newValue=$(expr substr "$value$spaces" 1 "$length")





                                                share|improve this answer















                                                If you’re willing to place an arbitrary upper limit
                                                on the number of spaces to add
                                                (and you obviously are,
                                                as your case statement can’t handle a length greater than 20),
                                                and you’re just talking about bytes
                                                (and not characters, which can be multi-byte),
                                                a simple way to pad a variable to a given length is:



                                                # 75 spaces
                                                spaces=" "
                                                ︙
                                                length=20
                                                ︙
                                                newValue=$(expr substr "$value$spaces" 1 "$length")






                                                share|improve this answer















                                                share|improve this answer



                                                share|improve this answer








                                                edited Jun 14 at 1:37


























                                                answered Jun 13 at 21:59









                                                Scott

                                                6,21332347




                                                6,21332347




















                                                    up vote
                                                    0
                                                    down vote













                                                    Core idea



                                                    for elem in "$localarrayname[@]"; do
                                                    localtoarray+=( "$(printf '<%-*.*s>n' "$p" "$p" "$elem")" )
                                                    done


                                                    Simple var



                                                    Using printf to add a variable count of spaces is very simple (the asterisk is the count):



                                                    $ printf '<%-*s>' 8 hello ; echo
                                                    <hello >


                                                    It could even be used to either extend or cut an string to a count:



                                                    $ printf '<%-*.*s>' 8 8 "TestingHello" ; echo
                                                    <TestingH>


                                                    Fixed trailing string



                                                    Using variable substitution we can add a fixed string to a variable:



                                                    $ var=hello
                                                    $ printf '<%s>n' "$var/%/"xxx""
                                                    <helloxxx>


                                                    That could be expanded to an array of values:



                                                    $ var=( hello world test )
                                                    $ printf '<%s>n' "$var[@]/%/"xxx""
                                                    <helloxxx>
                                                    <worldxxx>
                                                    <testxxx>


                                                    Array of values.



                                                    However, to add a variable count of spaces to an array we need to use a loop.

                                                    We can use a function to pass the list of values (only printing):



                                                    padarray() p=$1; shift
                                                    for elem; do
                                                    printf '<%-*.*s>n' "$p" "$p" "$elem"
                                                    done


                                                    array=( foo qux quuux alongerstring )
                                                    padarray 15 "$array[@]"


                                                    It prints:



                                                    $ ./script
                                                    <foo >
                                                    <qux >
                                                    <quuux >
                                                    <alongerstringto>


                                                    Indirect array.



                                                    To pass the arguments to a new array using the array(s) names (indirect):



                                                    padarray() local p=$1;
                                                    local -n localarrayname=$2 localtoarray=$3
                                                    localtoarray=()
                                                    for elem in "$localarrayname[@]"; do
                                                    localtoarray+=( "$(printf '<%-*.*s>n' "$p" "$p" "$elem")" )
                                                    done


                                                    array=( foo qux quuux alongerstringtotest )
                                                    padarray 12 array paddedarray
                                                    printf '%sn' "$paddedarray[@]"


                                                    Which on execution prints a similar result:



                                                    $ ./script
                                                    <foo >
                                                    <qux >
                                                    <quuux >
                                                    <alongerstrin>


                                                    Better pad count.



                                                    Adding a more robust count number of padding characters ($p):



                                                    p=$1//[!0-9] # Select only numeric digits.
                                                    (( 0<=p && p<=999 )) && return 2 # Return on error. Count out of range.


                                                    Final



                                                    We end with this script:



                                                    #!/bin/bash

                                                    padarray()


                                                    array=( bash bish bosh "" foo qux quuux "A Longer String To Test" )
                                                    padarray 20 array paddedarray
                                                    printf '%sn' "$paddedarray[@]"





                                                    share|improve this answer

























                                                      up vote
                                                      0
                                                      down vote













                                                      Core idea



                                                      for elem in "$localarrayname[@]"; do
                                                      localtoarray+=( "$(printf '<%-*.*s>n' "$p" "$p" "$elem")" )
                                                      done


                                                      Simple var



                                                      Using printf to add a variable count of spaces is very simple (the asterisk is the count):



                                                      $ printf '<%-*s>' 8 hello ; echo
                                                      <hello >


                                                      It could even be used to either extend or cut an string to a count:



                                                      $ printf '<%-*.*s>' 8 8 "TestingHello" ; echo
                                                      <TestingH>


                                                      Fixed trailing string



                                                      Using variable substitution we can add a fixed string to a variable:



                                                      $ var=hello
                                                      $ printf '<%s>n' "$var/%/"xxx""
                                                      <helloxxx>


                                                      That could be expanded to an array of values:



                                                      $ var=( hello world test )
                                                      $ printf '<%s>n' "$var[@]/%/"xxx""
                                                      <helloxxx>
                                                      <worldxxx>
                                                      <testxxx>


                                                      Array of values.



                                                      However, to add a variable count of spaces to an array we need to use a loop.

                                                      We can use a function to pass the list of values (only printing):



                                                      padarray() p=$1; shift
                                                      for elem; do
                                                      printf '<%-*.*s>n' "$p" "$p" "$elem"
                                                      done


                                                      array=( foo qux quuux alongerstring )
                                                      padarray 15 "$array[@]"


                                                      It prints:



                                                      $ ./script
                                                      <foo >
                                                      <qux >
                                                      <quuux >
                                                      <alongerstringto>


                                                      Indirect array.



                                                      To pass the arguments to a new array using the array(s) names (indirect):



                                                      padarray() local p=$1;
                                                      local -n localarrayname=$2 localtoarray=$3
                                                      localtoarray=()
                                                      for elem in "$localarrayname[@]"; do
                                                      localtoarray+=( "$(printf '<%-*.*s>n' "$p" "$p" "$elem")" )
                                                      done


                                                      array=( foo qux quuux alongerstringtotest )
                                                      padarray 12 array paddedarray
                                                      printf '%sn' "$paddedarray[@]"


                                                      Which on execution prints a similar result:



                                                      $ ./script
                                                      <foo >
                                                      <qux >
                                                      <quuux >
                                                      <alongerstrin>


                                                      Better pad count.



                                                      Adding a more robust count number of padding characters ($p):



                                                      p=$1//[!0-9] # Select only numeric digits.
                                                      (( 0<=p && p<=999 )) && return 2 # Return on error. Count out of range.


                                                      Final



                                                      We end with this script:



                                                      #!/bin/bash

                                                      padarray()


                                                      array=( bash bish bosh "" foo qux quuux "A Longer String To Test" )
                                                      padarray 20 array paddedarray
                                                      printf '%sn' "$paddedarray[@]"





                                                      share|improve this answer























                                                        up vote
                                                        0
                                                        down vote










                                                        up vote
                                                        0
                                                        down vote









                                                        Core idea



                                                        for elem in "$localarrayname[@]"; do
                                                        localtoarray+=( "$(printf '<%-*.*s>n' "$p" "$p" "$elem")" )
                                                        done


                                                        Simple var



                                                        Using printf to add a variable count of spaces is very simple (the asterisk is the count):



                                                        $ printf '<%-*s>' 8 hello ; echo
                                                        <hello >


                                                        It could even be used to either extend or cut an string to a count:



                                                        $ printf '<%-*.*s>' 8 8 "TestingHello" ; echo
                                                        <TestingH>


                                                        Fixed trailing string



                                                        Using variable substitution we can add a fixed string to a variable:



                                                        $ var=hello
                                                        $ printf '<%s>n' "$var/%/"xxx""
                                                        <helloxxx>


                                                        That could be expanded to an array of values:



                                                        $ var=( hello world test )
                                                        $ printf '<%s>n' "$var[@]/%/"xxx""
                                                        <helloxxx>
                                                        <worldxxx>
                                                        <testxxx>


                                                        Array of values.



                                                        However, to add a variable count of spaces to an array we need to use a loop.

                                                        We can use a function to pass the list of values (only printing):



                                                        padarray() p=$1; shift
                                                        for elem; do
                                                        printf '<%-*.*s>n' "$p" "$p" "$elem"
                                                        done


                                                        array=( foo qux quuux alongerstring )
                                                        padarray 15 "$array[@]"


                                                        It prints:



                                                        $ ./script
                                                        <foo >
                                                        <qux >
                                                        <quuux >
                                                        <alongerstringto>


                                                        Indirect array.



                                                        To pass the arguments to a new array using the array(s) names (indirect):



                                                        padarray() local p=$1;
                                                        local -n localarrayname=$2 localtoarray=$3
                                                        localtoarray=()
                                                        for elem in "$localarrayname[@]"; do
                                                        localtoarray+=( "$(printf '<%-*.*s>n' "$p" "$p" "$elem")" )
                                                        done


                                                        array=( foo qux quuux alongerstringtotest )
                                                        padarray 12 array paddedarray
                                                        printf '%sn' "$paddedarray[@]"


                                                        Which on execution prints a similar result:



                                                        $ ./script
                                                        <foo >
                                                        <qux >
                                                        <quuux >
                                                        <alongerstrin>


                                                        Better pad count.



                                                        Adding a more robust count number of padding characters ($p):



                                                        p=$1//[!0-9] # Select only numeric digits.
                                                        (( 0<=p && p<=999 )) && return 2 # Return on error. Count out of range.


                                                        Final



                                                        We end with this script:



                                                        #!/bin/bash

                                                        padarray()


                                                        array=( bash bish bosh "" foo qux quuux "A Longer String To Test" )
                                                        padarray 20 array paddedarray
                                                        printf '%sn' "$paddedarray[@]"





                                                        share|improve this answer













                                                        Core idea



                                                        for elem in "$localarrayname[@]"; do
                                                        localtoarray+=( "$(printf '<%-*.*s>n' "$p" "$p" "$elem")" )
                                                        done


                                                        Simple var



                                                        Using printf to add a variable count of spaces is very simple (the asterisk is the count):



                                                        $ printf '<%-*s>' 8 hello ; echo
                                                        <hello >


                                                        It could even be used to either extend or cut an string to a count:



                                                        $ printf '<%-*.*s>' 8 8 "TestingHello" ; echo
                                                        <TestingH>


                                                        Fixed trailing string



                                                        Using variable substitution we can add a fixed string to a variable:



                                                        $ var=hello
                                                        $ printf '<%s>n' "$var/%/"xxx""
                                                        <helloxxx>


                                                        That could be expanded to an array of values:



                                                        $ var=( hello world test )
                                                        $ printf '<%s>n' "$var[@]/%/"xxx""
                                                        <helloxxx>
                                                        <worldxxx>
                                                        <testxxx>


                                                        Array of values.



                                                        However, to add a variable count of spaces to an array we need to use a loop.

                                                        We can use a function to pass the list of values (only printing):



                                                        padarray() p=$1; shift
                                                        for elem; do
                                                        printf '<%-*.*s>n' "$p" "$p" "$elem"
                                                        done


                                                        array=( foo qux quuux alongerstring )
                                                        padarray 15 "$array[@]"


                                                        It prints:



                                                        $ ./script
                                                        <foo >
                                                        <qux >
                                                        <quuux >
                                                        <alongerstringto>


                                                        Indirect array.



                                                        To pass the arguments to a new array using the array(s) names (indirect):



                                                        padarray() local p=$1;
                                                        local -n localarrayname=$2 localtoarray=$3
                                                        localtoarray=()
                                                        for elem in "$localarrayname[@]"; do
                                                        localtoarray+=( "$(printf '<%-*.*s>n' "$p" "$p" "$elem")" )
                                                        done


                                                        array=( foo qux quuux alongerstringtotest )
                                                        padarray 12 array paddedarray
                                                        printf '%sn' "$paddedarray[@]"


                                                        Which on execution prints a similar result:



                                                        $ ./script
                                                        <foo >
                                                        <qux >
                                                        <quuux >
                                                        <alongerstrin>


                                                        Better pad count.



                                                        Adding a more robust count number of padding characters ($p):



                                                        p=$1//[!0-9] # Select only numeric digits.
                                                        (( 0<=p && p<=999 )) && return 2 # Return on error. Count out of range.


                                                        Final



                                                        We end with this script:



                                                        #!/bin/bash

                                                        padarray()


                                                        array=( bash bish bosh "" foo qux quuux "A Longer String To Test" )
                                                        padarray 20 array paddedarray
                                                        printf '%sn' "$paddedarray[@]"






                                                        share|improve this answer













                                                        share|improve this answer



                                                        share|improve this answer











                                                        answered Jun 14 at 7:59









                                                        Isaac

                                                        6,3041632




                                                        6,3041632






















                                                             

                                                            draft saved


                                                            draft discarded


























                                                             


                                                            draft saved


                                                            draft discarded














                                                            StackExchange.ready(
                                                            function ()
                                                            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f449535%2fbash-editing-contents-of-array-from-within-function%23new-answer', 'question_page');

                                                            );

                                                            Post as a guest













































































                                                            Popular posts from this blog

                                                            How to check contact read email or not when send email to Individual?

                                                            Displaying single band from multi-band raster using QGIS

                                                            How many registers does an x86_64 CPU actually have?