for ループを使用して、シェル スクリプトに与えられた引数を解析したいと考えています。ここで、3 つの引数があると仮定すると、次のような
for i in $1 $2 $3
処理が必要ですが、引数の数を予測できないため、範囲に RegEx を使用し、最後の引数の数として $# を使用したいと考えました。これらの RegEx を for ループで使用する方法がわかり
for i in $[1-$#]
ません。動作しないようなものを試しました。ループは 1 回だけ実行され、1-$# が計算され、正規表現としては使用されません。
3 に答える
基本
句for
を指定しない場合、デフォルトでループはコマンドライン引数をループします。in
for arg; do
echo "$arg"
done
明示的にしたい場合は、すべての引数を として取得できます"$@"
。上記のループは次と同等です。
for arg in "$@"; do
echo "$arg"
done
bash の man ページから:
特殊パラメータ
$@
— 1 から始まる定位置パラメーターに展開します。展開が二重引用符内で発生すると、各パラメーターは個別の単語に展開されます。つまり、"$@"
と同等"$1" "$2" ...
です。二重引用符で囲まれた展開が単語内にある場合、最初のパラメーターの展開は元の単語の先頭部分と結合され、最後のパラメーターの展開は元の単語の最後の部分と結合されます。位置パラメータがなく、何"$@"
も$@
展開されない場合 (つまり、それらは削除されます)。
高度
負荷の高い引数の処理にはgetopt
+shift
が適しています。getopt
コマンドラインを前処理して、ユーザーが引数を指定する方法にある程度の柔軟性を与えます。たとえば、 に展開-xzf
され-x -z -f
ます。--
フラグをファイル名から分離するすべてのフラグの後に引数を追加します。これにより、先頭のダッシュにバーフを付けずにcat -- -my-file
の内容を表示するために実行できます。-my-file
サイズについては、次の定型コードを試してください。
#!/bin/bash
eval set -- "$(getopt -o a:bch -l alpha:,bravo,charlie,help -n "$0" -- "$@")"
while [[ $1 != -- ]]; do
case "$1" in
-a|--alpha)
echo "--alpha $2"
shift 2
;;
-b|--bravo)
echo "--bravo"
shift
;;
-c|--charlie)
echo "--charlie"
shift
;;
-h|--help)
echo "Usage: $0 [-a ARG] [-b] [-c]" >&2
exit 1
;;
esac
done
shift
-a
各オプションには、と など、短いものと長いものがあることに注意してください--alpha
。フラグは-a
引数を取るため、呼び出しで and として指定され、ケースの最後に a がありa:
ます。alpha:
getopt
shift 2
あなたが目指していたものに近い引数を反復する別の方法は、次のようになります。
for ((i=1; i<=$#; i++))
do
echo "${@:i:1}"
done
しかし、for arg
John Kugelman が示した構文ははるかに優れています。ただし、配列のスライスが役立つ場合もあります。また、このバージョンでは、ジョンの場合と同様に、引数の配列はそのまま残されます。を使用shift
すると、その要素が破棄されます。
角括弧でやろうとしていたことは、正規表現ではないことに注意してください。
代わりに何か他のことをすることをお勧めします:
while [ -n "$1" ] ; do
# Do something with $1
shift
# Now whatever was in $2 is now in $1
done
このshift
キーワードは、$2 の内容を $1 に、$3 を $2 に、というように移動します。
引数を考えてみましょう:
a b c d
の後shift
、引数は次のようになります。
b c d
while ループを使用すると、任意の数の引数を解析でき、次のようなこともできます。
while [ -n "$1" ] ; do
if [ "$1" = "-f" ] ; then
shift
if [ -n "$1" ] ; then
myfile="$1"
else
echo "-f needs an additional argument"
end
fi
shift
done
引数が配列であり、 $n がその配列のインデックスであると想像してください。shift
は最初の要素を削除するため、インデックス 1 は の前にインデックス 2 にあった要素を参照するようになりましたshift
。私の言いたいことを理解していただければ幸いです。