Cookbooks
スクリプティングのための応用的なコードスニペット集っぽいもの。 基本的な文法機能の解説は別に書く。
See Also:
NOTE:
- このページに書いているが、実はPOSIX対応の機能もあるかもしれない。
joinとsplit
join:
arr=(a "b c" $'d\ne' f)
# ',' で結合
str="$(IFS=,; echo "${arr[*]}")"
IFS=, eval 'str="${arr[*]}"'
# ', ' で結合
str=$(printf ", %s" "${arr[@]}")
str=${str:2}
split:
str=$'a,b c,d\ne,f'
IFS=, eval 'arr=($str)'
参考:
複数行のコメントアウト
:
とヒアドキュメントを組み合わせる。
: << "__EOCOMMENT__"
コメントアウトしたいコード
__EOCOMMENT__
参考:
論理演算
((2 > 1)) # $? => 0
((1 > 1)) # $? => 1
(($(seq 1 3 | wc -w) > 2)) # $? => 0
if true; then echo ok; fi #=> ok
数値の操作
i=0
echo $((i++)) #=> 0
echo $((++i)) #=> 2
連番によるループ
$ n=0
$ for i in $(seq $n $((n + 2))); do echo $i; done
0
1
2
正規表現でグループ化と後方参照
マッチした文字列は、グループ化されたものも含めてBASH_REMATCH配列変数に格納される。
# bash
if [[ "2020-06-24" =~ ^([0-9]{4})-([0-9]{2})-([0-9]{2})$ ]] ; then
ymd="${BASH_REMATCH[0]}" #=> 2020-06-24
year="${BASH_REMATCH[1]}" #=> 2020
month="${BASH_REMATCH[2]}" #=> 06
day="${BASH_REMATCH[3]}" #=> 24
fi
参考:
多重ループとbreak, continue
break 2
や continue 2
のように後ろに数字を与えることで、上の階層のループを抜けられるようだ。
Example:
for ((i=1; i <= 4; i++)); do
for ((j=1; j <= 3; j++)); do
echo "(i, j) = ($i, $j)"
if ((i > 2)); then
if ((j == 2)); then
echo End of loop
break 2
fi
elif ((i > 1 && j == 2)); then
continue 2
fi
echo blah blah
done
echo "[$i] end"
done
実行結果:
(i, j) = (1, 1)
blah blah
(i, j) = (1, 2)
blah blah
(i, j) = (1, 3)
blah blah
[1] end
(i, j) = (2, 1)
blah blah
(i, j) = (2, 2)
(i, j) = (3, 1)
blah blah
(i, j) = (3, 2)
End of loop
参考:
文字列操作
部分文字列の削除
以下、 Bash scripting より。
${var%pattern}
… 後方からパターンの最短マッチを削除${var%%pattern}
… 後方からパターンの最長マッチを削除${var#pattern}
… 前方からパターンの最短マッチを削除${var##pattern}
… 前方からパターンの最長マッチを削除
パスからディレクトリ名やファイル名を取り出すのによく使う。
fullpath=/a/b/c.txt
echo ${fullpath##*/} # c.txt
echo ${fullpath%/*} # /a/b
filename=d.e.txt
echo ${filename%.*} # d.e
echo ${filename##*.} # txt
たぶん、Bash に限らず POSIX で使える。
下に載ってる。
http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_02
文字列の部分切り出し
$ echo $str
1234567890
$ echo ${str:3:4}
4567
参考:
文字列を部分的に置換
${var/x/y}
…$var
文字列のx
をy
に置換(1回のみ)${var//x/y}
…$var
文字列のx
をy
に置換(全てマッチ)