$ @ 最初のパラメータを除外

$ @ 最初のパラメータを除外

次の方法で実行されるシェルスクリプトを作成する必要があります。

./myscript arg1 arg2_1 arg2_2 arg2_3 ....... arg2_#

スクリプトに for ループがあります。

for i in $@

しかし、私が知っている限り、$ @は$ 1から$($#-1)まで含まれています。しかし、私のプログラムの場合、$ 1は$ 2 $ 3 $ 4などと大きく異なります。 $2から最後まで繰り返したいです。どうすればいいですか?ありがとう:)

答え1

まず、$@引用符がなければ意味がないので、使用しないでください。参照()とリストのコンテキスト$@でのみ使用できます。"$@"

for i in "$@"リストのコンテキストでは資格がありますが、ここでは位置引数を繰り返すための標準的で最も移植可能でシンプルな形式は次のとおりです。

for i
do something with "$i"
done

2番目の要素から始めて要素を繰り返すには、標準的で最も移植可能な方法は次のものを使用することですshift

first_arg=$1
shift # short for shift 1
for i
do something with "$i"
done

その後、shift元のコンテンツは$1リストから削除され(しかし私たちはそれをに保存しました$first_arg)、元のコンテンツ$2はにあります$1。位置パラメータは次のとおりです。移動する 1左の位置(shift 2移動2の場合...) したがって、デフォルトでは、ループは前の2番目のパラメータから最後のパラメータまで繰り返されます。

bash(and zshand ksh93、しかしそれがすべてです)を使用するもう1つの方法は、次のことです。

for i in "${@:2}"
do something with "$i"
done

ただし、これは標準構文ではないため、 でsh使用しないでください#! /bin/sh -

zshまたは では、yash次のこともできます。

for i in "${@[3,-3]}"
do something with "$i"
done

3番目の引数から3番目と最後の引数まで繰り返します。

では配列とも呼ばれますzsh。したがって、配列の先頭または末尾から要素をポップするには、次のようにすることもできます。$@$argv

argv[1,3]=() # remove the first 3 elements
argv[-3,-1]=()

(次のように書くことshiftもできます)1=()zsh

では、bash組み込みを使用して要素にのみ割り当てることができるので、$@最後setに3つの要素をポップするには、次の手順を実行します。

set -- "${@:1:$#-3}"

そして3番目から最後の3番目まで繰り返します。

for i in "${@:3:$#-5}"
do something with "$i"
done

POSIXlyで最後の3つの要素をポップするには、"$@"ループを使用する必要があります。

n=$(($# - 3))
for arg do
  [ "$n" -gt 0 ] && set -- "$@" "$arg"
  shift
  n=$((n - 1))
done

答え2

私の考えでは、あなたがshift埋め込まれたものが欲しいと思います。 、toなど$2に名前が変更されました。$1$3$2

このように:

shift
for i in "$@"; do
    echo $i
done

答え3

常に原始的なアプローチがあります。

first=1
for i
do
        if [ "$first" ]
        then
                first=
                continue
        fi
        something with "$i"
done

これはそのまま残り$@(後で使用したい場合)、各パラメータを単に繰り返しますが、最初のパラメータは処理しません。

答え4

Bashでは、明示的な索引付けを使用してこのループを作成することもできます。

for ((i=2; i<=$#; ++i)); do
  process "${!i}"
done

これは2番目から最後まですべてのパラメータを繰り返します。最後のパラメーターを除外するには、次のようにします。

for ((i=1; i<=$#-1; ++i)); do
  process "${!i}"
done

他のすべてのパラメータのみを使用するには、次のように記述します。

for ((i=1; i<=$#; i+=2)); do
  process "${!i}"
done

この後ろに隠された物語は山水バージョンfor組み込み、結合するパラメータ数$#そして可変間接${…}

良い適用は、これを使用して、指定されたオプションがそれに続く引数を値として使用するかどうかをループ内で決定できることです。そうであれば、増分i(たとえば、書き込み: $((++i)))して次の値を使用し、反復中にスキップします。

関連情報