it-swarm-ja.com

$ @第一引数を除く

このように実行するシェルスクリプトを記述する必要があります。

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

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

for i in [email protected]

ただし、知っているように、$ @には$ 1から$($#-1)までが含まれます。しかし、私のプログラムでは$ 1は$ 2 $ 3 $ 4などとは明らかに異なります。$ 2から最後までループしたいのですが、どうすればこれを実現できますか?ありがとうございました:)

46
user40780

まず、引用符なしの[email protected]は意味がないため、使用しないでください。 [email protected]は引用符付き("[email protected]")およびリストコンテキストでのみ使用する必要があります。

for i in "[email protected]"はリストコンテキストと見なされますが、ここでは、位置パラメーターをループ処理するために、標準的で最も移植性が高く、より単純な形式を示します。

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に追加されました。位置パラメータはshifted1の位置が左にあります(shift 2を使用して2だけシフトします...)。つまり、基本的に、ループは2番目の引数であったものから最後の引数までループします。

bash(およびzshksh93ですが、それだけです)では、代わりに次のようにします。

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では、[email protected]$argv配列とも呼ばれます。したがって、配列の最初または最後から要素をポップするには、次のようにすることもできます。

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

shiftzsh1=()と書くこともできます)

bashでは、set組み込みの[email protected]要素にのみ割り当てることができるため、最後から3つの要素をポップするには、次のようになります。

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

そして、3番目から最後の3番目にループするには:

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

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

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

shift組み込みが必要だと思います。 $2$1$3$2など.

このような:

shift
for i in "[email protected]"; do
    echo $i
done
10
John

穴居人のアプローチは常にあります:

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

これは[email protected]そのまま(後で使用したい場合)、すべての引数をループしますが、最初の引数は処理しません。

2
Scott

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 builtinarithmetic バージョンと、 argument-count _$#_ および 変数間接指定_${…}_

素敵なアプリケーションの1つは、これを使用して、ループ内で、指定されたオプションがそれに続く引数を値として取るかどうかを決定できることです。ある場合は、iをインクリメントして(たとえば、: $((++i))を書き込んで)、次の値を消費し、反復中にスキップします。

1
MvG