2017-01-27 4 views
5

Представьте, я создал массив так:Заменить пустой элемент в массиве Баша

IFS="|" read -ra ARR <<< "zero|one|||four" 

Теперь

echo ${#ARR[@]} 
> 5 
echo "${ARR[@]}" 
> zero one four 
echo "${ARR[0]}" 
> zero 
echo "${ARR[2]}" 
> # Nothing, because it is empty 

Вопрос заключается в том, как я могу заменить пустые элементы с другой строкой?

Я попытался

${ARR[@]///other} 
${ARR[@]//""/other} 

ни один из них не работал.

Я хочу, чтобы это как выход:

zero one other other four 
+0

Очевидно, что я могу написать цикл, но более кратким решением было бы неплохо – stackoverflower

+0

'" $ {обр [ 2]: - other} "', но 'printf '% s \ n" "$ {arr [@]: - other}" 'does not, что имеет смысл, но очень жаль, потому что трюк в [параметр Shell расширение по массивам] (http://stackoverflow.com/q/37698108/1983854). Я думаю, что цикл будет необходим – fedorqui

+0

@sat, я просто давал способ создать массив. Очевидно, существует много других способов создания массива. – stackoverflower

ответ

4

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

$ IFS="|" read -ra ARR <<< "zero|one|||four" 
$ for i in "${ARR[@]}"; do echo "${i:-other}"; done 
zero 
one 
other 
other 
four 

Где:

${parameter:-word}

Если параметр не установлен или нулевой, раскрытие слова заменены. В противном случае значение параметра заменяется.

Чтобы сохранить их в новом массиве, просто сделайте так, присоединяя с +=(element):

$ new=() 
$ for i in "${ARR[@]}"; do new+=("${i:-other}"); done 
$ printf "%s\n" "${new[@]}" 
zero 
one 
other 
other 
four 
3

Если вы хотите заменить все пустые значения (на самом деле изменения списка), вы можете сделать это:

for i in "${!ARR[@]}" ; do ARR[$i]="${ARR[$i]:-other}"; done 

Что выглядит следующим образом отступа (более читаемый, я бы сказал):

for i in "${!ARR[@]}" 
do 
    ARR[$i]="${ARR[$i]:-other}" 
done 
+0

Я попытался создать массив с тремя элементами ('ARR [12]' = "", 'ARR [123]' = foo, 'ARR [3456]' = bar), затем выполнил команду, которую я предложил, и он содержал ожидаемый результат ('other'' foo' 'bar'), в тех же позициях, что и раньше.Не могли бы вы уточнить, в каких условиях вы думаете, что это не сработает? – Fred

+0

Я тоже тестировал его с помощью ассоциативного массива (хотя я не думаю, что это было предназначено для OP), и, похоже, он работает в моей оболочке. – Fred

+0

Согласен, неправильно интерпретирован с похожим синтаксисом, который я пробовал локально, с радостью делал бы '+ 1', но OP настаивал на ответе без циклов. – Inian

Смежные вопросы