bashで普段こう書いているけど、実はこういう書き方もあるんですよというのをまとめてみました。
->の右側がmanに載ってるテク名です。
例えばどういったものが書けるかはガチャガチャした前回の記事で…。
`command` -> Command Substitution
書く量は増えるけど、視認性が良い(ネストした時が特に)。
尚、これは書き方が違うだけでどっちもCommand Substitutionです。
before
hosts_data=`grep \`uname -n\` /etc/hosts`
after
hosts_data=$(grep $(uname -n) /etc/hosts)
尚、Command Substitutionでcatをする場合、以下のように書けます。(catより高速らしい…)
before
hosts_entry=$(cat /etc/hosts)
after
hosts_entry=$(< /etc/hosts)
echo -> Here Strings
噛ませる為のechoはやめる。単独では使えないので注意。
before
echo "1+5+7^2" | bc
after
bc <<<"1+5+7^2"
echo >txt; echo >txt ... -> group command
処理をまとめて早く処理。
before
echo aa >a.txt
echo bb >>a.txt
echo ccc >>a.txt
after
{
echo aa
echo bb
echo ccc
} >a.txt
command >tmp.txt -> Process Substitution
余計な一時ファイルを使わなくて済む。
before
commandA >comA_tmp.txt
commandB >comB_tmp.txt
diff comA_tmp.txt comB_tmp.txt
rm comA_tmp.txt comB_tmp.txt
after
diff <(commandA) <(commandB)
var is null then set var -> Parameter Expansion
変数が空文字か設定されていないときは「:=」か「:-」で。
「:=」は変数に値が設定されます。「:-」は一時的。
before
a=
if [ -z "${a}" ] ; then
a="poi"
fi
echo ${a}
after
echo ${a:=poi}
sed -> Parameter Expansion
${parameter/pattern/string}の形で書くのがベースです。
文頭置換(#がパターンの一文字目の時)
before
a="/usr/local/bin";echo ${a} | sed "s@^.*/@/s@"
after
a="/usr/local/bin";echo ${a/#*\//\/s}
文末置換(%がパターンの一文字目の時)
before
b="200MB";echo ${b} | sed 's/B$/iB/'
after
b="200MB";echo ${b/%B/iB}
該当箇所全置換(/がパターンの一文字目の時)
before
c="a1b2c3d4";echo ${c} | sed 's/[0-9]//g'
after
c="a1b2c3d4";echo ${c//[0-9]}
1 2 3 4 5 -> Brace Expansion
数列
before
echo 1 3 5 7 9 11
after
echo {1..11..2}
文字列
before
touch data_a data_b data_c ......... data_z
after
touch data_{a..z}
expr -> Arithmetic Expansion
計算にexprはNo。ただ、有効桁数はbcよりしょぼい。
before
x=$(expr 1 + 1)
after
x=$((1 + 1))
おまけ 一時的に環境変数を変える
後ろのコマンドにだけ影響を与える。
LANG=C PAGER=less man bash
〆
大体どれもより簡潔に書けるようになるので、認知度が上がってほしいところです。
尚、古いbashだと対応していない場合があるので注意。
(古いSolaris環境にリリースしたらシェルがこけた…)