シェルスクリプトで可変長引数を扱う

f:id:suganoo:20200124175712p:plain
シェルスクリプトを実行するときに、いくつになるかわからない引数を全て使いたいときがあります。
例えば作ったファイルを全て何か処理したいとき、いくつの引数になるかわかりません。

そういったときに可変長引数を使うと便利です。

可変長引数は ${@} ですべての引数を扱うことができます。
1つづつ扱いたければ下記のようにループも使えます。

for N in "${@}" ;
do
  echo ${N}
done

抽出することも可能で、例えば2番目から3つ値を取得したいときは

# a b c d e f の時
echo "${@:2:3}"   # --> b c d

で取得することができます。

これと引数の数を表す $# を組み合わせれば、引数の最後2つだけ取得するといったこともできます。

# a b c d e f の時
echo "${@:($# - 2):2}"   # --> e f

こんな感じですね。

#* も同じように扱えますが、少し挙動が違います。

下記に実行例を書いてみました。参考にしてみてください。

testtest.sh
--------------
echo "\${@} : "${@}
echo "\${@:4:3} : "${@:4:3}
echo
echo "\${*} : "${*}
echo "\${*:4:3} : "${*:4:3}
echo
echo "loop check \"\${@}\""
for N in "${@}" ;
do
  echo ${N}
done
echo
echo "loop check \"\${*}\""
for N in "${*}";
do
  echo ${N}
done
echo

NUM=2
echo "2 items from last  \${@:(\$# - ${NUM}):${NUM}} : "${@:($# - ${NUM}):${NUM}}

実行結果

$ sh testtest.sh 1 2 3 4 5 6 7 8 9 10 11 12
-----------
${@} : 1 2 3 4 5 6 7 8 9 10 11 12
${@:4:3} : 4 5 6

${*} : 1 2 3 4 5 6 7 8 9 10 11 12
${*:4:3} : 4 5 6

loop check "${@}"
1
2
3
4
5
6
7
8
9
10
11
12

loop check "${*}"
1 2 3 4 5 6 7 8 9 10 11 12

2 items from last  ${@:($# - 2):2} : 10 11