Upload
th0x0472
View
237
Download
0
Embed Size (px)
Citation preview
#ssmjp 2013.09.25.@th0x0472
MAN OF BASHINTO DEEPNESS
祝!Sphinx本発売
http://www.oreilly.co.jp/books/9784873116488/
サマリー。最近たくさんシェルスクリプト書いた。
bashのmanを読んだ。
イロイロできるじゃん、すげー!
というわけで、manで調べたこと、試したことを整理してシェアしますよ。
ディープと感じるかどうかは個人差があります。
ディープと感じるかどうかは個人差があります。
大事なことなので2回言います。
正直、色々できすぎておなかいっぱい。今回は変数展開。
「今回は」といいましたが、次回があるかは僕の検証能力次第です。
コマンドラインの操作をラクにするアレコレもありません。
まずはおさらい% cat ./example0.sh
#!/bin/bash -x
VAR="bar"
echo ${VAR}
echo $VAR
実行すると./example0.sh
+ VAR=bar
+ echo bar
bar
+ echo bar
bar
${VAR}
このとき、変数名のあとに記号+アルファ付けるとイロイロできます。
Use Default Values.word に指定した値がデフォルト値になる。
parameter に値が代入されていれば、その値が使われる。
parameter になにも代入されていなければ、デフォルト値が使われる。
parameter に word は代入されない。
${parameter:-word}
${parameter:-word}#!/bin/bash -x
echo ${VAR}echo ${VAR:-"foo"}
echo ${VAR}
VAR="bar"echo ${VAR}
+ echo+ echo foofoo
+ echo
+ VAR=bar+ echo barbar
${parameter:=word}デフォルト値を代入する。wordに指定した値がデフォルト値になる。
parameter に値が代入されていれば、その値が使われる。
parameter になにも代入されていなければ、デフォルト値が使われる。
parameter に word は代入される。
${parameter:=word}#!/bin/bash -x
echo ${VAR}echo ${VAR:="foo"}
echo ${VAR}
VAR="bar"echo ${VAR}
+ echo+ echo foofoo
+ echo foofoo
+ VAR=bar+ echo barbar
使ってみる(スクリプト)
% cat example1.sh
#!/bin/bash -x
PARAM1=${1:-"Default Value"}
echo ${PARAM1}
使ってみる (実行結果)% ./example1.sh
+ PARAM1='Default Value'
+ echo Default Value
Default Value
% ./example1.sh "foo bar"
+ PARAM1='foo bar'
+ echo foo bar
foo bar
${parameter:?word}
値が代入されていなければ、エラーになってスクリプトがそこで終了する。このとき word に指定した文が出力される。
リターンコードは1でした。
${parameter:?word}#!/bin/bash -x
VAR="ABC"
echo ${VAR:?"error."}
+ VAR=ABC
+ echo ABC
ABC
${parameter:?word}#!/bin/bash -x
VAR=""
echo ${VAR:?"error."}
+ VAR=
./example4.sh: line 4: VAR: error.
使ってみる(スクリプト)
% cat ./example2.sh
#!/bin/bash -x
PARAM1=${1:?"何か引数を指定してよ"}
echo ${PARAM1}
使ってみる (実行結果)% ./example2.sh "foo bar"
+ PARAM1='foo bar'
+ echo foo bar
foo bar
% ./example2.sh
./example2.sh: line 2: 1: 何か引数を指定してよ
% echo $?
1
${parameter:+word}Use Alternate Value.word に指定した値が Alternate Value になる。
parameter に値が代入されていれば、Alternate Value が使われる。
parameter になにも代入されていなければ、からっぽのまま。
parameter に word は代入されない。
${parameter:+word}#!/bin/bash -x
VAR="foo"
echo ${VAR}
echo ${VAR:+"bar"}
echo ${VAR}
+ VAR=foo
+ echo foo
foo
+ echo bar
bar
+ echo foo
${parameter:+word}#!/bin/bash -x
echo ${VAR}
echo ${VAR:+"bar"}
VAR="foo"
echo ${VAR}
+ echo
+ echo
+ VAR=foo
+ echo foo
foo
${parameter:offset}${parameter:offset:length}
offset から{末尾まで,lengthだけ}切り出す。
parameter の値は変更されない。
offset のカウントは0から始まる。
offset が文字列長より大きいとからっぽになる。
offset に負の値を指定するとスルーされる。
${parameter:offset}
#!/bin/bash -x
VAR="1234"
echo ${VAR:2}
+ VAR=1234
+ echo 34
34
${parameter:offset:length}
#!/bin/bash -x
VAR="1234"
echo ${VAR:1:2}
+ VAR=1234
+ echo 23
23
${parameter:offset:length}
#!/bin/bash -x
VAR="にほんご"
echo ${VAR:1:2}
+ VAR=$'?\201??\201??\202\223?\201\224'
+ echo $'?\201??\202\223'
ほん
${parameter:offset} はecho ${VAR} | cut -c N- を置き換えられる。
${parameter:offset:length} はecho ${VAR} | cut -c N-M を置き換えられる。
${parameter:offset}${parameter:offset:length}
${parameter:offset}
#!/bin/bash -x
VAR="01234567"
echo ${VAR:4}
echo ${VAR} | cut -c 5-
+ VAR=01234567
+ echo 4567
4567
+ echo 01234567
+ cut -c 5-
4567
${parameter:offset:length}
#!/bin/bash -x
VAR="01234567"
echo ${VAR:2:2}
echo ${VAR} | cut -c 3-4
+ VAR=01234567
+ echo 23
23
+ echo 01234567
+ cut -c 3-4
23
${#parameter}
parameterに代入されている値の長さが返される。
${#parameter}#!/bin/bash -x
VAR_E="English"echo ${#VAR_E}
VAR_J="にほんご"echo ${#VAR_J}
+ VAR_E=English+ echo 77
+ VAR_J=$'?\201??\201??\202\223?\201\224'+ echo 44
スクリプト
#!/bin/bash -xVAR="0123456789"echo ${VAR:$((${#VAR} - 5)):2}
実行結果
+ VAR=0123456789+ echo 5656
入れ子もOK!
楽しくなってくるけどやり過ぎに注意。
${VAR:$((${#VAR}-5)):2}${#VAR} → VAR の長さ = 10$((${#VAR} - 5)) = 10 - 5 = 5${VAR:$((${#VAR} - 5)):2} = ${VAR:5:2}
VAR=”01234567890”
offset 5 の位置の文字は、5。そこから length=2 で、 56 が切り出される。
ご利用は計画的に。
${parameter#word}${parameter%word}parameter の{先頭,末尾}でwordにマッチした部分を削除した値を返す。
# → 先頭
% → 末尾
${parameter#word}#!/bin/bash -x
VAR="0123456789"
echo ${VAR#012}
+ VAR=0123456789
+ echo 3456789
3456789
${parameter%word}#!/bin/bash -x
VAR="0123456789"
echo ${VAR%789}
+ VAR=0123456789
+ echo 0123456
0123456
合わせ技は失敗#!/bin/bash -x
VAR="0123456789"
echo ${VAR#123%789}
+ VAR=0123456789
+ echo 0123456789
0123456789
リベンジ・・・失敗。#!/bin/bash -x
VAR="0123%789456789"
echo ${VAR#123%789}
+ VAR=0123%789456789
+ echo 0123%7894567890123%789456789
実は・・・
${parameter##word}
${parameter%%word}
もあるんだけど・・・・
正直、違いが分かりませんでした。教えてエライ人。
${parameter#word} , ${parameter%word}
manによれば、この二つは、shortest match
${parameter##word} , ${parameter%%word}
manによれば、 この二つは、longest match
何となく意味は分かるような、でも違いがハッキリ分かる例を作れませんでした。
parameter のうち pattern に最初にマッチした部分を string に置き換える。
${parameter/pattern/string}
${parameter/pattern/string}
#!/bin/bash -x
VAR="ABCDEFG"
echo ${VAR/ABC/abc}
+ VAR=ABCDEFG
+ echo abcDEFG
abcDEFG
${parameter/pattern/string}
pattern が # ではじまると、 parameter の先頭でマッチしたとき string に置き換えられる。
${parameter/pattern/string}#!/bin/bash -x
VAR="ABCDEFG"
echo ${VAR/#ABC/abc}
echo ${VAR/#DEF/def}
echo ${VAR/DEF/def}
+ VAR=ABCDEFG
+ echo abcDEFG
abcDEFG
+ echo ABCDEFG
ABCDEFG
+ echo ABCdefG
ABCdefG
${parameter/pattern/string}
pattern が % ではじまると、 parameter の末尾でマッチしたとき string に置き換えられる。
${parameter/pattern/string}#!/bin/bash -x
VAR="ABCDEFG"
echo ${VAR/%EFG/efg}
echo ${VAR/%DEF/def}
echo ${VAR/DEF/def}
+ VAR=ABCDEFG
+ echo ABCDefg
ABCDefg
+ echo ABCDEFG
ABCDEFG
+ echo ABCdefG
ABCdefG
${parameter/pattern/string}
string が空っぽだと、parameter のうちpattern にマッチした部分が削除される。
${parameter/pattern/string}#!/bin/bash -x
VAR="ABCDEFG"
echo ${VAR/DEF}
echo ${VAR/DEF/}
+ VAR=ABCDEFG
+ echo ABCG
ABCG
+ echo ABCG
ABCG
${parameter/pattern/string}
parameter のうち pattern に最初にマッチした部分を string に置き換える。
つまり、pattern に複数箇所マッチしても、置き換えられるのは最初の1回だけ。
${parameter/pattern/string}#!/bin/bash -x
VAR="ABCABC"
echo ${VAR/AB/ab}
+ VAR=ABCABC
+ echo abCABC
abCABC
${parameter/pattern/string}
patternの大文字・小文字は区別される。
${parameter/pattern/string}#!/bin/bash -x
VAR="abCABC"
echo ${VAR/AB/XY}
+ VAR=abCABC
+ echo abCXYC
abCXYC
${parameter/pattern/string}
pattern に . (ドット、ピリオド)を指定しても任意の1文字にはならない
${parameter/pattern/string}#!/bin/bash -x
VAR="ABCD"
echo ${VAR/./Z}
+ VAR=ABCD
+ echo ABCD
ABCD
${parameter/pattern/string}
pattern に ? を指定すると任意の1文字になる。
${parameter/pattern/string}#!/bin/bash -x
VAR="ABCD"
echo ${VAR/?/Z}
echo ${VAR/??/XY}
+ VAR=ABCD
+ echo ZBCD
ZBCD
+ echo XYCD
XYCD
${parameter/pattern/string}
pattern に * を指定すると何でもマッチする。
${parameter/pattern/string}#!/bin/bash -x
VAR="ABCD"
echo ${VAR/*/XYZ}
echo ${VAR/A*/XYZ}
echo ${VAR/B*/XYZ}
+ VAR=ABCD
+ echo XYZ
XYZ
+ echo XYZ
XYZ
+ echo AXYZ
AXYZ
${parameter/pattern/string}
pattern に [ABC] [1-9] なんかもいけた。
${parameter/pattern/string}#!/bin/bash -x
VAR="ABCD"
echo ${VAR/[BC]/X}
+ VAR=ABCD
+ echo AXCD
AXCD
${parameter/pattern/string}#!/bin/bash -x
VAR="0123"
echo ${VAR/[1-4]/X}
+ VAR=0123
+ echo 0X23
0X23
僕は力尽きました
しかし、変数展開だけでみてもまだ手を出せてない機能があります。
配列関連の機能とか
“変数名”に展開する機能とか
いつか踏み込んでみたいです。
おしまい。ご静聴ありがとうございました。