Home > Back-end >  How can I remove the last character of an element in an array and add it to the beginning of another
How can I remove the last character of an element in an array and add it to the beginning of another

Time:06-08

I have the following code:

white='\e[0;37m'
array=("{$white}aaaa" "{$white}aaa" "{$white}aaa")

Using cuad=$( echo -e "$array[0]}" | grep -o a | wc -l I can count the "a" in the array obtaining 4.

After doing that, using remainder=$(( $cuad % 3 )) I calculate the remainder dividing by 3 of the previous result.

What I want to do is:

If the remainder is equal to 1, I want to remove the last character of the element I am evaluating and add it in the beginning of the next element of the array.

If the remainder is equal to 2, I want to remove the 2 last characters of the element I am evaluating and add them in the beginning of next element of the array.

I am trying to make the number of characters in each element of the array a multiple of 3. What I don't know is how to remove the last characters of an element and I also don't know how to add characters to the beginning of another element. In this example, the desired output for my array would be ($whiteaaa $whiteaaa $whiteaaaa) as I don't care if the last element does not contain a multiple of 3.

Another example: array=({$white}aaaaaaaa {$white}aaa {$white}aaa) and the final result would be: array=({$white}aaaaaa {$white}aaa {$white}aaaaa) having multiples of 3 in the 2 first elements and the rest in the last one

My idea is doing something similar to this:

for ((i=0; i<3; i  )); do
    cuad=$( echo -e "$array[i]}" | grep -o a | wc -l
    remainder=$(( $cuad % 3 ))
    if [[ $remainder -eq 1 ]]
    then
        #remove last character of element i  
        #add that character to the element i 1
    elif [[ $remainder -eq 2 ]]
        #remove 2 last characters of element i  
        #add them to the element i 1
    fi
done

CodePudding user response:

You can loop through the indexes of the array elements; then, for each element, append the exceeding number of a characters of the previous iteration to it, compute the exceeding ones (for the next iteration) and strip them from the current element:

#!/bin/bash
array=("X█████" "Y██" "Z███")

excess=''
for i in "${!array[@]}"
do
    array[i] =$excess

    [[ ${array[i]} =~ █ $ ]]

    case $(( ${#BASH_REMATCH} % 3 )) in
      0) excess='';;
      1) excess=█;;
      2) excess=██;;
    esac

    array[i]=${array[i]%"$excess"}
done
array[i] =$excess

In this example, array would then become:

array=("X███" "Y███" "Z████")
Notes:
  • for i in "${!array[@]}" loops over the indexes of the bash array array

  • array[i] =$excess appends the exceeding number of of the previous iteration to the current array element.

  • [[ ${array[i]} =~ █ $ ]] matches the longest sequence of characters located at the end of the current array element; the result is stored in BASH_REMATCH[0], so you can use the shortcut $BASH_REMATCH to get it.

  • $(( ${#BASH_REMATCH} % 3 )) computes the modulo 3 of the length of $BASH_REMATCH.
    The case switch defines a string representing the exceeding number of (according to possible results of the modulo 3).

  • array[i]=${array[i]%"$excess"} strips the exceeding number of from the current array element.

  • The last array[i] =$excess is for (re)appending the exceeding number of to the last array element.

  • Related