Расширение параметров оболочки на массивах

Скажем, я прочитал некоторые данные в массив Bash:

$ IFS=" " read -a arr <<< "hello/how are/you iam/fine/yeah"

Теперь я хочу напечатать первый /поле для каждого элемента в массиве.

Что я делаю, так это перебираю элементы и использую расширение параметров оболочки, чтобы удалить все с первого раза /:

$ for w in "${arr[@]}"; do echo "${w%%/*}"; done
hello
are
iam

Тем не менее, так как printf позволяет нам печатать все содержимое массива в одном выражении:

$ printf "%s\n" "${arr[@]}"
hello/how
are/you
iam/fine

... интересно, есть ли способ использовать расширение параметра оболочки ${w%%/*} во время использования printfвместо того, чтобы перебирать все элементы и делать это против каждого.

2 ответа

Решение

О, я только что нашел способ: просто используйте расширение параметра нормально, только это против ${arr[@]} вместо ${arr}!

$ IFS=" " read -a arr <<< "hello/how are/you iam/fine/yeah"
$ printf "%s\n" "${arr[@]%%/*}"
hello
are
iam

Вики Грега помогли здесь:

Расширение параметра для массивов

Массивы BASH удивительно гибки, потому что они хорошо интегрированы с другими расширениями оболочки. Любое расширение параметра, которое может быть выполнено для скалярного или отдельного элемента массива, может в равной степени применяться ко всему массиву или к набору позиционных параметров, так что все члены расширяются одновременно, возможно, с дополнительной операцией, сопоставленной каждому элементу.

$ a=(alpha beta gamma)  # assign to our base array via compound assignment
$ echo "${a[@]#a}"      # chop 'a' from the beginning of every member
lpha beta gamma
$ echo "${a[@]%a}"      # from the end
alph bet gamm
$ echo "${a[@]//a/f}"   # substitution
flphf betf gfmmf

Основываясь на ответе @fedorqui, если OP хочет вывести массив вместо строки, это сработало для меня:

      a=(alpha beta gamma)
newArr=( "${a[@]//a/f}" )

PS Я лично пришел к этому сообщению, чтобы вывести массив после выполнения подстановок для каждого элемента массива.

Другие вопросы по тегам