こんにちは。よっしーです(^^)
今日は、bashのパラメータ展開をご紹介します。
先日dateコマンドをご紹介しました。dateコマンドでは、現在日時を取得できるのですが、取得した現在日時から年や月、日など、特定の数値だけを取得したい場面がありました。その場面で、パラメータ展開を用いた取得をしたので、パラメータ展開についてシェアしたいと思いました。
実行環境
この記事で使用されているコマンドは下記の環境で実行されています。
% sw_vers
ProductName: macOS
ProductVersion: 13.2.1
BuildVersion: 22D68
% sysctl machdep.cpu.brand_string
machdep.cpu.brand_string: Apple M1 Max
bash-3.2$ bash --version
GNU bash, version 3.2.57(1)-release (arm64-apple-darwin22)
Copyright (C) 2007 Free Software Foundation, Inc.
パラメータ展開とは
Bashには、パラメータ展開と呼ばれる機能があります。パラメータ展開は、変数や引数から情報を取得するための機能で、シェルスクリプトの書き方を簡潔にするのに役立ちます。
以下は、いくつかの一般的なパラメータ展開の例です。
- 変数の長さを取得する
変数の長さを取得するには、${#variable}を使用します。
$ my_var="Hello World"
$ echo ${#my_var}
11
上記のコードは、”Hello World”の長さである11を表示します。
- パターンに一致する文字列を置換する
パターンに一致する文字列を置換するには、${parameter/pattern/string}を使用します。
$ my_var="Hello World"
$ echo ${my_var/Hello/Goodbye}
Goodbye World
上記のコードは、「Hello World」を「Goodbye World」に置換して表示します。
- パラメーターの存在を確認する
パラメータが存在するかどうかを確認するには、${parameter+value}を使用します。
$ if [ -z ${my_var+x} ]; then echo "my_var is unset"; else echo "my_var is set to '$my_var'"; fi
my_var is set to 'Hello World'
上記のコードは、my_varが定義されていない場合、「my_var is unset」と表示し、そうでない場合は「my_var is set to ‘Hello World’」と表示します。
- パラメータのデフォルト値を設定する
パラメータが未定義の場合、デフォルト値を設定することができます。
$ echo ${my_var:-"Default Value"}
Default Value
上記のコードは、my_varが未定義の場合、”Default Value”を表示します。
- パラメーターを配列として展開する
パラメーターを配列として展開するには、${parameter[@]}を使用します。
$ my_array=(one two three)
$ echo "${my_array[@]}"
one two three
上記のコードは、”one two three”を表示します。
これらは、Bashのパラメータ展開の一部の例です。Bashには、さまざまなパラメータ展開の方法があります。詳細については、Bashのマニュアルページを参照してください。
パラメータ展開の一覧
下記のコマンドを実行するとパラメータ展開の一覧を取得できます。実行環境によって、出力結果が異なると思います。
bash-3.2$ man bash | grep "^\s*\${.*}$" | tr -d " "
${parameter}
${parameter:-word}
${parameter:=word}
${parameter:?word}
${parameter:+word}
${parameter:offset}
${parameter:offset:length}
${!prefix*}
${!prefix@}
${!name[@]}
${!name[*]}
${#parameter}
${parameter#word}
${parameter##word}
${parameter%word}
${parameter%%word}
${parameter/pattern/string}
詳しくは下記のサイトを御覧ください。
${parameter}
# 代入
bash-3.2$ value="yossi"
# 代入した値の表示
bash-3.2$ echo ${value}
yossi
# 大文字小文字は区別される
bash-3.2$ echo ${Value}
${parameter:-word}
変数が未定義や値が空のときに、:- 以降の文字列が使用されます。変数に値は代入されません。
# 変数が未定義
bash-3.2$ unset value
bash-3.2$ echo ${value}
bash-3.2$ echo ${value:-default_value}
default_value
bash-3.2$ echo ${value}
# 値が空でない場合
bash-3.2$ value="yossi"
bash-3.2$ echo ${value}
yossi
bash-3.2$ echo ${value:-default_value}
yossi
# 値が空の場合
bash-3.2$ value=""
bash-3.2$ echo ${value}
bash-3.2$ echo ${value:-default_value}
default_value
bash-3.2$ echo ${value}
${parameter:=word}
変数が未定義や値が空のときに、:= 以降の文字列が使用されます。変数に値は代入されます。
# 値が未定義
bash-3.2$ unset value
bash-3.2$ echo ${value}
bash-3.2$ echo ${value:=default_value}
default_value
bash-3.2$ echo ${value}
default_value
${parameter:?word}
変数が未定義や値が空のときに、エラーになる。:?以降のwordは、エラー文言として表示される。
# 変数が未定義
bash-3.2$ unset value
bash-3.2$ echo ${value:?}
bash: value: parameter null or not set
bash-3.2$ echo ${value:?unknown}
bash: value: unknown
# 値が空
bash-3.2$ value=
bash-3.2$ echo ${value:?}
bash: value: parameter null or not set
bash-3.2$ echo ${value:?unknown}
bash: value: unknown
${parameter:+word}
:- の逆で、値が空でない場合にwordの値が利用されます。変数への代入は行われません。
# 変数が未定義
bash-3.2$ unset value
bash-3.2$ echo ${value}
bash-3.2$ echo ${value:+overwrite}
bash-3.2$ echo ${value}
# 変数の値が空でない
bash-3.2$ value=yossi
bash-3.2$ echo ${value}
yossi
bash-3.2$ echo ${value:+overwrite}
overwrite
bash-3.2$ echo ${value}
yossi
# 変数の値が空
bash-3.2$ value=
bash-3.2$ echo ${value}
bash-3.2$ echo ${value:+overwrite}
bash-3.2$ echo ${value}
${parameter:offset}
offsetで指定された文字目より後ろの文字から最後までが表示される。
# 2文字目よりも後ろの文字が出力される
bash-3.2$ value=yossi
bash-3.2$ echo ${value:2}
ssi
${parameter:offset:length}
offsetで指定された文字目より後ろの文字からlengthの文字数までが表示される。
# 2文字目よりも後ろの文字が1文字分出力される
bash-3.2$ value=yossi
bash-3.2$ echo ${value:2:1}
s
${!prefix*}
# P*にあてはまる変数が表示される
bash-3.2$ echo ${!P*}
PATH PIPESTATUS PPID PS1 PS2 PS4 PWD
${!prefix@}
# P@にあてはまる変数が表示される
bash-3.2$ echo ${!P@}
PATH PIPESTATUS PPID PS1 PS2 PS4 PWD
${!name[*]}
# インデックスリストが表示される
bash-3.2$ my_array=(foo bar baz)
bash-3.2$ echo ${!my_array[*]}
0 1 2
${!name[@]}
# インデックスリストが表示される
bash-3.2$ my_array=(foo bar baz)
bash-3.2$ echo ${!my_array[@]}
0 1 2
${#parameter}
parameterに設定されている値の文字数をカウントします。
bash-3.2$ value=yossi
bash-3.2$ echo ${#value}
5
${parameter#word}
wordに値の前方から最初に一致するまでの部分を除去します。
bash-3.2$ value=yossi
bash-3.2$ echo ${value#*s}
si
${parameter##word}
wordに値の前方から最後に一致するまでの部分を除去します。
bash-3.2$ value=yossi
bash-3.2$ echo ${value##*s}
i
${parameter%word}
wordに値の後方から最初に一致するまでの部分を除去します。
bash-3.2$ value=yossi
bash-3.2$ echo ${value%s*}
yos
${parameter%%word}
wordに値の後方から最後に一致するまでの部分を除去します。
bash-3.2$ value=yossi
bash-3.2$ echo ${value%%s*}
yo
${parameter/pattern/string}
patternをstringに置換します。
bash-3.2$ value=yossi
# 最初のpatterにマッチした箇所だけ置換
bash-3.2$ echo ${value/s/S}
yoSsi
# すべて置換
bash-3.2$ echo ${value//s/S}
yoSSi
おわりに
Bashのパラメータ展開は、変数の値を変更したり、テキストの操作を行うための機能です。パラメータ展開を使用することの主なメリットは以下のとおりです。
- 変数の値を変更できる
パラメータ展開を使用することで、変数の値を簡単に変更できます。たとえば、${variable/old/new}
というパターンを使用すると、変数variable
の値の中の最初のold
文字列をnew
に置換することができます。これにより、変数の値を効率的に操作することができます。
- テキストの操作が容易になる
パラメータ展開を使用することで、テキストの操作が簡単になります。たとえば、${string:position:length}
というパターンを使用すると、変数string
の中で、position
から始まるlength
文字の部分文字列を取得することができます。また、${string##pattern}
や${string%%pattern}
などのパターンを使用することで、文字列の先頭や末尾にあるパターンを削除することもできます。
- シェルスクリプトの記述が簡潔になる
パラメータ展開を使用することで、同じ処理を繰り返す必要がなくなり、シェルスクリプトの記述が簡潔になります。たとえば、${variable:=default}
というパターンを使用すると、変数variable
が定義されていない場合にdefault
の値を代入することができます。
- プログラムの可読性が向上する
パラメータ展開を使用することで、プログラムの可読性が向上することがあります。たとえば、${variable//pattern/replacement}
というパターンを使用すると、変数variable
の中のすべてのpattern
文字列をreplacement
に置換することができます。このコマンドは、文字列の置換を一度に行うという意図が明確であるため、プログラムの可読性が向上します。
これらのメリットにより、パラメータ展開は、Bashスクリプトで広く使用される機能の一つとなっています。
コマンドを使用しなくてもパラメータ展開で実現可能な処理もあると思うので、どこか頭の片隅にでもおいておくと助かる場面があるかも知れません。
また明日お会いしましょう!
コメント