bash: $i がコマンドライン引数と同じ場合: if [[ " $@ " =~ " $i " ]]

bash: $i がコマンドライン引数と同じ場合: if [[ " $@ " =~ " $i " ]]

$i がコマンドライン引数 (Bash スクリプトで) と同じであることを確認するには、次のようにします。

 if [[ " $@ " =~ " $i " ]]

もっと良い方法がありますか?

私の言葉は、より推薦することができ、より汎用性がありますが、ほぼ同様に簡単な方法です。

私の言葉が正しい場合、上記は$ iと各コマンドライン引数にスペースが含まれていないときに機能します。ほとんどの場合、問題はありませんが、簡単な修正やその他の簡単な改善があるかもしれません。

この特別なケースでは$ *がうまくいくと思いますが、一般的にもっとお勧めですか?違いはここで確認できます。https://stackoverflow.com/questions/3898665/what-is-in-bash

答え1

に切り替えるオプションがある場合は、zsh次のようにする必要があります。

set 'foo bar' 1:2 $'a\nb'
i='foo bar'
if (( n = $argv[(Ie)$i] )); then
  print -r -- "$i is found among the positional parameters, in \${$n} at least"
fi

では、cshと同様に、zsh位置パラメータを配列に使用することもできます。ソート$argvI下付き文字記号下付き文字をパターンとして処理し、拡張時に値がパターンと一致Iする最後の要素のインデックスを返します(見つからない場合は0)。パターンマッチングeの代わりにxactマッチングに使用されます。eここでは、結果をnkshスタイルの算術式に代入します(式が通常のようにゼロ以外の値である場合はtrueを返します)。

また、withのすべての要素に一致するパターンをzsh設定することもできます。$@

pattern="(${(j[|])${(b)@}})"

そこ、b パラメータ拡張フラグglobをエスケープしてj[|]結果要素をに関連付けると、たとえば次のようなパターンに|なります。(foo|bar|\*|)set -- foo bar '*' ''

次のように使用されます。

if [[ $i = $~pattern ]]...

ただし、位置引数のリストが空の場合、()空の文字列と誤って一致するパターンが生成されます。

最終目標が位置引数でも見つかる配列要素を見つけることであれば、zshの配列交差演算子を使用できます${A:*B}

set a A 'x y'
array=(a b 'x y' a)
print -r Found in argv: ${array:*argv}

$iBashまたはPOSIXシェルで文字がわかっている場合、または位置引数が表示されない場合は、次のことができます。

IFS=: # join "$*" with :
case ":${*}:" in
  (*:"$i":*) printf '%s\n' "$i is among the positional parameters";;
esac

kshismの代わりに標準のsh構文を使用し、[[ ... ]]移植性がないという点(bashバージョンでも)(=~bashの=~単純な文字列と比較して非テキスト文字列のブロックも含む)を除いて、アプローチと似ています。ここでは、任意のスペースとは異なり、ユースケースまたは位置パラメータに表示される可能性が最も低い項目が何であるかを知る必要があります。また、リストコンテキストの外部で使用される場合はほとんど意味がなく、動作はシェルによって異なります。位置引数に関連付ける最初の文字が指定されるように明示的に指定された非リストコンテキストでは意味があります。=:$i"$@""$*"$IFS

[[ ... ]]代わりにkshスタイルを使用できますcase

if [[ ":${*}:" = *:"$i":* ]]...

任意の値を使用するにはbashループを使用する必要があります。

found=false
for arg do
  if [ "$arg" = "$i" ]; then
    found=true
    break
  fi
done
if "$found"; then
  printf '%s\n' "$i is among the positional parameters"
fi

ヘルパー関数を定義することもできます。

among() {
  local needle="$1" arg
  shift
  for arg do
    [ "$arg" = "$needle" ] && return
  done
  false
}
if among "$i" "$@"; then
  printf '%s\n' "$i is among the positional parameters"
fi

答え2

$iBashスクリプトでコマンドライン引数と同じであることを確認するには、次のようにします。

if [[ " $@ " =~ " $i " ]]

最良のシナリオは、コマンドラインをチェックして次のことを確認することです。含むの価値$i。たとえば、i=theコマンドライン引数の1つがある場合、the elephant条件は一致します。

しかし、whichも使用しましたが$@、二重引用符の中で使用すると、一般的に引用された一連の引数の単語に拡張されます。ここでは、"$*".bash[[ … ]]$@$@

そうする方が良いでしょうが、それでも影響を受けます。含む代わりに同じ:

if [[ " $* " =~ " $i " ]]

以下を確認してください。$i 同じコレクション内のすべてのコマンドラインパラメータを繰り返す必要があると思います。

success=false
for arg in "$@"; do [[ "$arg" = "$i" ]] && { success=true; break; }; done

if "$success"

これをよりエレガントに表現すると、次のようになります。もう一つの答え関数としてamong

関連情報