「シェルスクリプトの基礎 - 変数」の版間の差分

ナビゲーションに移動 検索に移動
166行目: 166行目:
  FILES=`ls`
  FILES=`ls`
  echo "$FILES"
  echo "$FILES"
</source>
<br><br>
== 変数展開機能 ==
変数展開の仕組みを利用すると、変数に格納された文字列を置換、変数の存在を確認、変数の初期値の指定等ができる。<br>
<br>
==== パターン照合演算子 ====
下表に示すように、変数展開の構文を使用すると、変数に格納された文字列の一部を置換した文字列を作成することができる。<br>
また、パターン部分において、ワイルドカード(*、?、[a-z]等)が使用できる。<br>
<center>
{| class="wikitable"
|-
! 構文 !! 意味
|-
| ${変数/パターン/置換文字列} || パターンに一致する部分を置換文字列に置き換える(1つだけ)
|-
| ${変数//パターン/置換文字列} || パターンに一致する部分を置換文字列に置き換える(すべて)
|-
| ${変数#パターン} || 先頭から最短一致でパターンに一致する部分を取り除く
|-
| ${変数##パターン} || 先頭から最長一致でパターンに一致する部分を取り除く
|-
| ${変数%パターン} || 末尾から最短一致でパターンに一致する部分を取り除く
|-
| ${変数%%パターン} || 末尾から最長一致でパターンに一致する部分を取り除く
|}
</center>
<br>
* 最初に一致する文字列のみ置換する。
<source lang="sh">
# 実行
X=aaabbbccc
Y=${X/b/B}
echo $Y
# 出力
aaaBbbccc
</source>
<br>
* パターンに一致する文字列を全て置換する。
<source lang="sh">
# 実行
X=aaabbbccc
Y=${X//b/B}
echo $Y
# 出力
aaaBBBccc
</source>
<br>
sedコマンドと同様の結果を、シェルスクリプトの機能だけで実現できていることがわかる。<br>
<source lang="sh">
X=aaabbbccc
Y=$(echo $X | sed -e 's/bbb/BBB/g')
</source>
<br>
* フルパスからbasenameを取り出す。
*: 以下の例では、/aaa/bbb/cccという絶対パスから、basenameのcccを抽出している。
*: */というパターンで、先頭から最長一致させて、/aaa/bbb/を取り除いている。
<source lang="sh">
# 実行
X=/aaa/bbb/ccc
Y=${X##*/}
echo $Y
# 出力
ccc
</source>
<br>
また、basenameを取得する場合、一般的に、basenameコマンドを使用した方が簡単である。<br>
<source lang="sh">
basename $X
</source>
<br>
* フルパスからdirnameを取り出す。
*: 以下の例では、/aaa/bbb/cccという絶対パスから、ディレクトリ名の/aaa/bbbを抽出している。
*: /*というパターンで、末尾から最短一致させて、/cccを取り除いている。
<source lang="sh">
# 実行
X=/aaa/bbb/ccc
Y=${X%/*}
echo $Y
# 出力
/aaa/bbb
</source>
<br>
また、ディレクトリ名を取得する場合、一般的に、dirnameコマンドを使用した方が簡単である。<br>
<source lang="sh">
dirname $X
</source>
<br>
* '#'以降のコメントを削除する。
*: #*というパターンで、末尾から最長一致させて、変数LINEの#以降の部分を削除している。
<source lang="sh">
# 実行
LINE="aaa bbb # This is a comment"
LINE=${LINE%%#*}
echo $LINE
# 出力
aaa bbb
</source>
<br>
==== 初期値 ====
<center>
{| class="wikitable"
|-
! 構文 !! 意味
|-
| ${変数:-word} || 変数が未定義の時、wordを返す。
|-
| ${変数:=word} || 変数が未定義の時、変数にwordを代入して返す。
|-
| ${変数:?}<br>${変数:?word} || 変数が未定義の時、エラーを表示する。
|-
| ${変数:+word} || 変数が定義されている時、wordを返す。
|}
</center>
* ${変数:-word}
*: 例えば、<code>X=${COUNT:-0}</code>と記述すると、変数<code>X</code>の値は変数<code>COUNT</code>の値が無ければ0を返す。
*: つまり、変数<code>COUNT</code>の初期値を0とみなして参照する。
*: <br>
*: この構文は、コマンドライン引数が省略された場合、初期値を設定するために使用できる。
*: 例えば、<code>FILENAME=${1:-input.txt}</code>とすると、変数<code>FILENAME</code>の値は、第1パラメータで指定された値または初期値のinput.txtとなる。
<br>
* ${変数:=word}
*: 例えば、X=${COUNT:=0}と記述すると、変数COUNTの値が無ければ、変数Xおよび変数COUNTに0を代入する。
*: ただし、変数に代入するため、コマンドライン引数や関数の引数の$1を参照する場合には、この方法は使用できない。
<br>
* ${変数:?word}
*: 例えば、以下のように記述すると、変数COUNTの値が無ければエラーを出力して終了する。
<source lang="sh">
# 実行
echo ${COUNT:?}
# 出力
-bash: count: パラメータが null または設定されていません
</source>
<br>
?の後ろに表示するメッセージを指定することもできる。<br>
<source lang="sh">
# 実行
echo ${COUNT:?パラメータが設定されていません}
# 出力
-bash: count: パラメータが設定されていません
</source>
<br>
* ${変数:+word}
*: 変数に値が代入されている場合、代わりにwordの値を返す。
*: 例えば、${COUNT:+1}は、変数COUNTが定義されていたら1と評価される。
<source lang="sh">
# 実行
COUNT=9999
echo ${COUNT:+1}
# 出力
1
</source>
<br>
<source lang="sh">
# 実行
COUNT=9999
unset COUNT
echo ${COUNT:+1}
# 出力
何も表示されない
</source>
<br>
==== 位置指定で部分文字列を抽出する ====
<center>
{| class="wikitable"
|-
! 構文 !! 意味
|-
| ${変数:offset} || offsetで指定した位置から末尾までの文字列を抽出する。
|-
| ${変数:offset:length} || offsetで指定した位置からlength分の文字列を抽出する。
|}
</center>
<br>
<source lang="sh">
# 実行
HOGE=ABCDEFGHIJ
echo ${HOGE:3}
# 出力
DEFGHIJ
</source>
<br>
<source lang="sh">
# 実行
HOGE=ABCDEFGHIJ
echo ${HOGE:3:4}
# 出力
DEFG
</source>
<br>
offsetやlength に負の値を指定して、末尾から文字列を抽出することもできる。<br>
ただし、offsetの前に1つ以上のスペースが必要である。(スペースを入れないと、${変数:-word}という形で初期値が指定されたとみなされる)<br>
<source lang="sh">
# 実行
HOGE=ABCDEFGHIJ
echo ${HOGE: -3}
# 出力
HIJ
</source>
<br>
<source lang="sh>
# 実行
HOGE=ABCDEFGHIJ
echo ${HOGE: -5:-2}
# 出力
FGH
  </source>
  </source>
<br><br>
<br><br>

案内メニュー