Редактирование элементов массива - удаление символов и вычитание 1 - PullRequest
1 голос
/ 02 апреля 2019

У меня есть массив, в котором есть два элемента, которые в текущем состоянии бесполезны, мне нужно удалить символ и вычесть один из них.

Я попытался удалить символ, чтобы поставитьчисло в уравнении, но оно, кажется, не сохраняет мои новые беззнаковые элементы в переменную.

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)

Однако, оно никогда не сдвинется с мертвой точки.Хотя это работает:

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

Это не так:

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

Я, очевидно, не понимаю, как обрезать символы и помещать их в новую переменную.

Ответы [ 2 ]

1 голос
/ 02 апреля 2019

В

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

вы делаете не то, что ожидаете.Сравните это с вашей рабочей версией:

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

Здесь вы используете echo для ввода sed.В первой строке ничего не дано sed.

Вы также ожидаете заменить результат выполнения его значением, чтобы сохранить его в var.Для этого вы должны использовать синтаксис подстановки команд:

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

И эта строка также является примером бесполезного использования эха.Было бы чище с здесь строкой :

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

Вы даже можете избежать использования sed, используя средства, предоставляемые bash:

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

Шаблон тот же, который вы использовали с добавлением / в начале, чтобы указать bash заменить все совпадения в строке (имитируя ваш g в sed).

0 голосов
/ 02 апреля 2019

Для определенного элемента,

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

... но ручной выбор элемента кажется странным, если только это не ваша структура данных.
Как насчет цикла?

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

Выход:

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