次の引数までコマンドライン引数オプションを繰り返します。

次の引数までコマンドライン引数オプションを繰り返します。

私が作業しているスクリプトに新しく追加されたものでは、zshがコマンドの次のフラグに達するまで、フラグに関連するパラメータを繰り返したいと思います。たとえば、ユーザーが次のように入力した場合:

datt -p Package1 Package2 Package3 --build

スクリプトはPackage1Package2およびPackage3それぞれを配列の位置に割り当てる必要があります。私の思考プロセスは次のとおりです。

packages=()
for i in "$@"; do
     packages+=("$i")
done

だから私の質問は、コマンドラインの次のフラグが表示されるまでこのループを続行するスクリプトをどのように書くのですか?質問の冒頭に示されているコマンド()を使用して、datt -p Package1 Package2 Package3 --buildforループが--buildパッケージ名をキャプチャするのを防ぎ、配列への文字列の追加を停止するにはどうすればよいですかPackageN

答え1

パラメータを正しく解析するのは面倒です。私はあなたが使用することをお勧めします選択を受ける(1)。ここで同じフラグを複数回指定できます。

datt -p Package1 -p Package2 -p Package3 --build

何らかの理由でフラグを再利用できない場合(何かはわかりませんが...)、パラメータを個々の項目に渡してスペースを区切ることもできます。

datt -p "Package1 Package2 Package3" --build

答え2

shiftこの解析を実行するには、配列が空になるまでwhileループを使用する方が簡単です。

packages=()
while (($#)); do
  case $1 in
    -p)
      while shift; [[ $1 != -* ]]; do
        packages+=($1)
      done
  esac
  shift
done

あなたはそれを使用することができますi 下付き文字記号内部ループを実行して、次のオプションを見つけます。$array[(i)PATTERN]は最初に一致する要素のインデックスですPATTERN。インデックスは1から始まるので、1を引いて残りの要素数を取得します。一致するものがない場合、PATTERN値は最後の要素のインデックスに1を加えた値なので、この場合もこのようなコードは機能します。

packages=()
while (($#)); do
  case $1 in
    -p) ((n = $@[(i)-*] - 1)); packages+=($@[1,$n]); shift $n;;
  esac
  shift
done

説明する構文は非標準です。このため、私はこれをしないことをお勧めします。ユーザーに混乱を与える可能性があるためです。通常datt -p Package1 Package2 Package3 --build同じことをしますdatt -p Package1 Package2 --build Package3

答え3

一般的に最も賢明な方法は、ループ内のすべてのオプションを見て、コンテンツを正しい場所に配置することです。通常、パラメータ解析ループでは処理されませんが、オプションの順序が重要な場合は意味があります。

たとえば、次のループ(Bashまたはzshの場合)は次のようになります。

#!/usr/bin/zsh
packages=()
while [ "$#" -gt 0 ]; do
    case $1 in
    -p)      echo "p option seen...";;
    --build) echo "--build option seen after ${#packages[@]} packages...";;
    *)       echo "adding package '$1'";
             packages+=("$1");;
    esac
    shift;
done

typeset -p packages;

減らす:

$ zsh dattest.sh -p foo bar doo --build
p option seen...
adding package 'foo'
adding package 'bar'
adding package 'doo'
--build option seen after 3 packages...
typeset -a packages=( foo bar doo )

関連情報