参考「3.4.1 Positional Parameters - Bash Reference Manual」
参考「3.4.2 Special Parameters - Bash Reference Manual」
参考「3.5.3 Shell Parameter Expansion - Bash Reference Manual」
1. 取得
参考「[シェル] 特殊パラメータ @ のパラメータ展開 - Qiita」
1.1. 全て
特殊パラメータを用いて全ての位置パラメータを取得することが出来ます。
コード | 意味 |
---|---|
$# |
位置パラメータの数 |
"$@" |
全ての位置パラメータをそれぞれ展開 |
"$*" |
全ての位置パラメータを展開して連結 |
ちなみに、パラメータ展開 "${parameter@Q}"
を用いて文字列をエスケープすることが出来ます。
#
function length() {
echo "$#"
}
#
function f() {
echo "$#"
echo "$@"
length "$@"
echo "${@@Q}"
length "${@@Q}"
echo "$*"
length "$*"
echo "${*@Q}"
length "${*@Q}"
}
f foo bar baz
3
foo bar baz
3
'foo' 'bar' 'baz'
3
foo bar baz
1
'foo' 'bar' 'baz'
1
1.2. 単独
位置が定数の場合、"$1"
や "${12}"
のようにして取得します。
他に間接展開や部分列を用いて単独の位置パラメータを取得する方法があります。
コード | 意味 |
---|---|
"$1" |
最初の位置パラメータ |
"${!offset}" |
$offset 番目の位置パラメータ |
"${@:$#}" "${@: -1}"
|
最後の位置パラメータ |
#
function f() {
echo "$1"
# echo "$12" # 間違い
echo "${12}"
}
f \'p1\' \'p2\' \'p3\' \'p4\' \'p5\' \'p6\' \'p7\' \'p8\' \'p9\' \'p10\' \'p11\' \'p12\'
#
function g() {
local -ri offset=2
echo "${!offset}"
}
g foo bar baz
#
function h() {
echo "${@:$#}"
echo "${@: -1}"
local -ri offset_last=$#
echo "${!offset_last}"
}
h foo bar baz
'p1'
'p12'
bar
baz
baz
baz
間接展開 "${!#}"
に関しては、Bash で POSIX モードを無効化している場合に使用可能です。
set -o posix
#
function f() {
# echo "${!#}" # エラー発生
set +o posix
echo "${!#}"
set -o posix
}
f foo bar baz
baz
1.3. 部分列
"${@:offset}"
"${@:offset:length}"
特殊パラメータ @
の場合、offset
に負の数を指定することは出来ますが、length
に負の数を指定することは出来ません。
部分列の終端を末尾からのオフセットで指定したい場合は、特殊パラメータ $#
を用いて計算します。
#
function f() {
echo "${@:2}"
echo "${@: -3}"
# echo "${@:-3}" # 間違い
local -ri offset=2
echo "${@:offset}"
}
f foo bar baz qux
#
function g() {
echo "${@:2:2}"
echo "${@: -3:2}"
# echo "${@:-3:2}" # 間違い
echo "${@:2:$#-2}"
# echo "${@:2:-1}" # エラー発生
local -ri offset=2
local -ri length=2
echo "${@:offset:length}"
}
g foo bar baz qux
bar baz qux
bar baz qux
bar baz qux
bar baz
bar baz
bar baz
bar baz
他に以下のような部分列の使い方があります。
部分列を含むコード | 意味 |
---|---|
"${@:1}" |
$@ |
"$1" "${@:2}" |
最初の位置パラメータを分割 |
"${@:1:$#-1}" "${@:$#}" "${@:1:$#-1}" "${@: -1}"
|
最後の位置パラメータを分割 |
#
function f() {
echo "${@:1}"
echo "$@"
echo "$1" '|' "${@:2}"
echo "${@:1:$#-1}" '|' "${@:$#}"
echo "${@:1:$#-1}" '|' "${@: -1}"
}
f foo bar baz
foo bar baz
foo bar baz
foo | bar baz
foo bar | baz
foo bar | baz
1.4. ループ
ループを用いて位置パラメータをそれぞれ取得することが出来ます。
参考「3.2.5.1 Looping Constructs - Bash Reference Manual」
#
function f() {
for p; do
echo -n "$p "
done
echo
local -i i
for (( i = 1; i <= $#; i++ )); do
echo -n "${!i} "
done
unset i
echo
}
f foo bar baz
#
function g() {
local -i i=1
while test $i -le $#; do
echo -n "${!i} "
let i++
done
unset i
echo
local -i i=1
while [ $i -le $# ]; do
echo -n "${!i} "
let i++
done
unset i
echo
local -i i=1
while [[ i -le $# ]]; do
echo -n "${!i} "
let i++
done
unset i
echo
local -i i=1
while (( i <= $# )); do
echo -n "${!i} "
let i++
done
unset i
echo
}
g foo bar baz
foo bar baz
foo bar baz
foo bar baz
foo bar baz
foo bar baz
foo bar baz
2. 設定
通常の代入文では位置パラメータの値を変更できませんが、set
コマンドを使用することで全ての位置パラメータを置き換えることができます。
参考「set - Bash Reference Manual」
set -- foo bar baz
echo "$@"
set -- FOO BAR BAZ
echo "$@"
foo bar baz
FOO BAR BAZ
3. 追加
set
コマンドで "$@"
を使用することで、前後に位置パラメータを追加することが出来ます。
3.1. 先頭
set -- foo bar
echo "$@"
set -- baz "$@"
echo "$@"
set -- foo bar
echo "$@"
set -- baz qux "$@"
echo "$@"
foo bar
baz foo bar
foo bar
baz qux foo bar
3.2. 末尾
set -- foo bar
echo "$@"
set -- "$@" baz
echo "$@"
set -- foo bar
echo "$@"
set -- "$@" baz qux
echo "$@"
foo bar
foo bar baz
foo bar
foo bar baz qux
4. 削除
4.1. 先頭
先頭の位置パラメータを削除する場合、shift
コマンドを使用します。
参考「shift - Bash Reference Manual」
set -- foo bar baz qux
echo "$@"
shift
echo "$@"
set -- foo bar baz qux
echo "$@"
shift 2
echo "$@"
foo bar baz qux
bar baz qux
foo bar baz qux
baz qux
4.2. 末尾
末尾の位置パラメータを削除する場合、部分列を取得し set
コマンドで全ての位置パラメータを置き換えます。
set -- foo bar baz qux
echo "$@"
set -- "${@:1:$#-1}"
echo "$@"
set -- foo bar baz qux
echo "$@"
set -- "${@:1:$#-2}"
echo "$@"
foo bar baz qux
foo bar baz
foo bar baz qux
foo bar
4.3. ループ
ループを用いて位置パラメータをそれぞれ取得しながら削除することが出来ます。
参考「3.2.5.1 Looping Constructs - Bash Reference Manual」
set -- foo bar baz
while test $# -gt 0; do
echo -n "$1 "
shift
done
echo
set -- foo bar baz
while [ $# -gt 0 ]; do
echo -n "$1 "
shift
done
echo
set -- foo bar baz
while [[ $# -gt 0 ]]; do
echo -n "$1 "
shift
done
echo
set -- foo bar baz
while (( $# > 0 )); do
echo -n "$1 "
shift
done
echo
foo bar baz
foo bar baz
foo bar baz
foo bar baz
5. 変換
5.1. 部分列
部分列を取得し set
コマンドで全ての位置パラメータを置き換えることで、部分列の位置パラメータを変換することが出来ます。
#
function command_qux() {
echo 'qux'
}
#
set -- foo bar baz
echo "$@"
set -- "$(command_qux "$1")" "${@:2}"
echo "$@"
set -- foo bar baz
echo "$@"
set -- "${@:1:$#-1}" "$(command_qux "${@:$#}")"
echo "$@"
set -- foo bar baz
echo "$@"
set -- "${@:1:$#-1}" "$(command_qux "${@: -1}")"
echo "$@"
foo bar baz
qux bar baz
foo bar baz
foo bar qux
foo bar baz
foo bar qux
5.2. 全て
一部のパラメータ展開は特殊パラメータ @
に対して使うと各位置パラメータに適用されます。
参考「[シェル] 特殊パラメータ @ のパラメータ展開 - Qiita」
set -- 'foo bar baz' 'foo bar baz' 'foo bar baz'
echo "${@#* }"
echo "${@##* }"
echo "${@% *}"
echo "${@%% *}"
set -- 'foo bar baz' 'foo bar baz' 'foo bar baz'
echo "${@/ /_}"
echo "${@// /_}"
echo "${@/#foo/***}"
echo "${@/%baz/***}"
set -- foo bar baz
echo "${@^}"
echo "${@^^}"
echo "${@^f}"
echo "${@^^a}"
set -- FOO BAR BAZ
echo "${@,}"
echo "${@,,}"
echo "${@,F}"
echo "${@,,A}"
set -- foo '\' \'
echo "${@@Q}"
bar baz bar baz bar baz
baz baz baz
foo bar foo bar foo bar
foo foo foo
foo_bar baz foo_bar baz foo_bar baz
foo_bar_baz foo_bar_baz foo_bar_baz
*** bar baz *** bar baz *** bar baz
foo bar *** foo bar *** foo bar ***
Foo Bar Baz
FOO BAR BAZ
Foo bar baz
foo bAr bAz
fOO bAR bAZ
foo bar baz
fOO BAR BAZ
FOO BaR BaZ
'foo' '\' \'