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 2continue 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 文字列の xy に置換(1回のみ)
  • ${var//x/y}$var 文字列の xy に置換(全てマッチ)

参考: bashの変数をsplitして配列を作る方法: 小粋空間