bash - 配列の各項目の前に要素を追加します。

bash - 配列の各項目の前に要素を追加します。

grep他のプログラムの出力から除外したい文字列を含む配列があります。-e各要素の前に1つずつ追加する必要があります。たとえば、

exclude=("$0" /usr/sbin/crond)
needs-restarting | grep -Fwiv "${exclude[@]}"

今、この場合、次のように各要素の前に追加--regexp=(または単に)できることがわかりました。-eexclude=( "${exclude[@]/#/--regexp=}" )

しかし、一般的にどうすればよいですか?私はこれを見つけましたが、おそらくより簡単な方法があります。

i=0
for elem in "${exclude[@]}"; do
  exclude[i]='-e'
  exclude[i+1]="$elem"
  ((i+=2))
done
declare -p exclude

答え1

4.4+ では、bash次のことができます。

readarray -td '' array < <(
  ((${#array[@]})) && printf -- '-e\0%s\0' "${array[@]}"
)

\0bash変数はとにかくNULバイトを含めることができないため、これは区切り文字として使用されます。配列が空ではないことがわかっている場合は、これをスキップできます((${#array[@]})) &&

例:

  • 今後:
    bash-5.0$ array=($'a\nb' '' 'c d' e)
    bash-5.0$ typeset -p array
    declare -a array=([0]=$'a\nb' [1]="" [2]="c d" [3]="e")
    
  • 後ろに:
    bash-5.0$ typeset -p array
    declare -a array=([0]="-e" [1]=$'a\nb' [2]="-e" [3]="" [4]="-e" [5]="c d" [6]="-e" [7]="e")
    

では、zsh配列圧縮演算子を使用できます。

opt=-e
(($#array == 0)) || array=("${(@)opt:^^array}")

それともこの複雑なもの:

set -o extendedglob # for (#m)
array=("${(Q@)"${(@z)array//(#m)*/-e ${(qq)MATCH}}"}")

-e <the-element-quoted>各要素を(フラグを使用)に置き換えてから、参照を要素のリストにqqz解析し(合計が分離されている)、-e引用<the-element-quoted>Q(および@空の要素を保持するために使用される引用符内の要素(存在する場合))を削除します。 )).

答え2

提案されたループを少し簡単にすることができます。

exclude_args=()
for elem in "${exclude[@]}"; do
  exclude_args+=('-e' "$elem")
done
exclude=("${exclude_args[@]}")   # Optional, if you want to replace the original array's contents

関連情報