Solebay Sharp
Solebay Sharp

Reputation: 533

Editing Array Elements - Remove Character and Subtract 1

I have an array which has two elements that are not useful in their current state, I need to remove a character and subtract one from them.

I have tried to strip the character so that I can put the number into an equation but it doesn't seem to save my new characterless elements into a variable.

array=(ab cd C5 ef gh R6 0.88)

#get rid of C
RemChar="${array[2]}" | sed 's/[A-Za-z]*//g'
#subtract 1 from 5
NewValue=(($RemoveChar-1))
#Replace Old Element
${array[2]}=NewValue

#get rid of R
RemChar="${array[5]}" | sed 's/[A-Za-z]*//g'
#subtract 1 from 6
NewValue=(($RemoveChar-1))
#Replace Old Element
${array[5]}=NewValue

#Now the new array 'should' be:
array=(ab cd 4 ef gh 5 0.88)

However, it never gets off the ground. Whilst this works:

echo "${array[2]}" | sed 's/[A-Za-z]*//g'

This does not:

RemChar="${array[2]}" | sed 's/[A-Za-z]*//g'
echo "$RemChar"

I'm obviously not grasping how to strip characters and put these in a new variable.

Upvotes: 1

Views: 396

Answers (2)

Paul Hodges
Paul Hodges

Reputation: 15378

For a specific element,

echo $(( ${array[2]#C} - 1 )) # explicitly remove C
4
echo $(( ${array[2]#?} - 1 )) # explicitly remove *any* first character
4
echo $(( ${array[2]//[a-zA-Z]/} - 1 )) # # explicitly remove all letters
4

...but manually selecting the element seems odd unless that's just your data structure.
How about a loop?

array=(ab cd C5 ef gh R6 0.88) # create the array

for ndx in "${!array[@]}" # loop over the indexes, 0-6
do if [[ "${array[ndx]}" =~ [[:alpha:]] ]] && # if there's a letter
      [[ "${array[ndx]}" =~ [[:digit:]] ]]    # AND a digit
   then # scrub the letter(s) and decrement the digit, 
        # assign the result over the original value.
        array[ndx]="$(( ${array[ndx]//[[:alpha:]]/} - 1 ))" 
   fi
done

declare -p array # show the new result set

Output:

declare -a array=([0]="ab" [1]="cd" [2]="4" [3]="ef" [4]="gh" [5]="5" [6]="0.88")

Upvotes: 0

Poshi
Poshi

Reputation: 5762

In

RemChar="${array[2]}" | sed 's/[A-Za-z]*//g'

you are not doing what you expect. Compare it with your working version:

echo "${array[2]}" | sed 's/[A-Za-z]*//g'

Here you are running echo to give an input to sed. In the first line, nothing is given to sed.

You are also expecting to substitute the result of the execution for its value to store it in the var. For this, you should use a command substitution syntax:

RemChar=$(echo "${array[2]}" | sed 's/[A-Za-z]*//g')

And this line is also an example of a Useless Use Of Echo. It would be cleaner with a here string:

RemChar=$(sed 's/[A-Za-z]*//g' <<< "${array[2]}")

You can even avoid the use of sed by using the facilities provided by bash:

RemChar="${array[2]//[A-Za-z]/}"

The pattern is the same you used with a / added at the beginning to tell bash to substitute all matches in the string (mimmicking your g in sed).

Upvotes: 1

Related Questions