shで変数をコマンドオプションパラメータに分割する

shで変数をコマンドオプションパラメータに分割する

スクリプト呼び出しで変数を反復パラメータに変換する最も効率的な方法を教えてくれる人はいますか?私はそれを適切に説明する方法がわかりませんが、例はそれ自体を教えています。少なくとも私は彼らがそうしたいです:)

例1:

# input
export DOMAINS="domain1.tld,domain2.tld"

# tranform to
./example-script.sh -d "domain1.tld" -d "domain2.tld"

例2(入力は奇数):

# input
export DOMAINS="domain1.tld"

# tranform to
./example-script.sh -d "domain1.tld"

[更新]最初の投稿にこのコンテンツを追加できなかったので申し訳ありません。

追加するコンテキスト:

  • DOMAINSはDockerコンテナに追加された環境変数です。
  • shコンテナにはシェルしかないため、zsh特定のbashオプションは効果がありません。
  • 初期bashタグを追加して申し訳ありません。

ベストアンサー1

以下を使用する方が簡単ですzsh

区切りリストを含むスカラー変数から,

DOMAINS="domain1.tld,domain2.tld"

s配列に分割,:

domains=( ${(s[,])DOMAINS} )

圧縮配列opt=( -d ):

opt=( -d )
./example-script.sh ${opt:^^domains}

これが他にサポートされている場合は、./example-script.sh中間配列をスキップして次のものを使用できます。-ddomain1.tld-d domain1.tld

./example-script.sh -d$^domains

Bashではループを使用できます。

IFS=, # split on ,
set -o noglob # disable glob
domains=( $DOMAINS ) # split+glob
args=()
for domain in "${domains[@]}"; do
  args+=( -d "$domain" )
done
./example-script.sh "${args[@]}"

または、シェル構文を使用してコードを生成できます。

IFS=, # split on ,
set -o noglob # disable glob
domains=( $DOMAINS ) # split+glob
if [ "${#domains[@]}" -gt 0 ]; then
  printf -v args ' -d %q' "${domains[@]}"
else
  args=
fi
shell_code="./example-script.sh$args"
eval -- "$shell_code"

これがさらにサポートされている場合は、./example-script.sh次のこともできます。-ddomain1.tld-d domain1.tld

IFS=, # split on ,
set -o noglob # disable glob
domains=( $DOMAINS ) # split+glob
./example-script.sh "${domains[@]/#-d}"

-d配列の各要素の前に追加します$domains

標準にはsh配列がなく、標準read -A/-aprintfありません%q(そしてそれを拡張としてサポートする実装が常にsh互換性のある参照を生成するわけではありません)。代わりに、上記の最初のbashメソッドを使用できます"$@"

IFS=, # split on ,
set -o noglob # disable glob
set --
for domain in $DOMAINS; do # split+glob
  set -- "$@" -d "$domain"
done
./example-script.sh "$@"

別のオプションは、分割を呼び出してawk互換sh性のあるコードを生成することです。

eval "./example-script.sh$(
  LC_ALL=C awk -v q="'" '
    function shquote(s) {
      gsub(q, q "\\\\" q q, s)
      return q s q
    }
    BEGIN {
      n = split(ENVIRON["DOMAINS"], domains, ",")
      for (i = 1; i <= n; i++)
        printf " -d %s", shquote(domains[i])
    }'
)"

おすすめ記事