memo

bash

条件文

変数

デフォルト値

HOGE=123 hoge.sh として実行するスクリプトで、変数 HOGE が省略された場合のデフォルト値を設定する。

#!/bin/bash
HOGE=${HOGE:-111}
echo $HOGE

hoge.sh と実行すると、111 が表示される。

日付

日付を取得する

日付(時刻)をファイル名にする

today=`date +%Y%m%d.txt`
echo hoge > ${today}

now=`date +%Y%m%d%H%M%S.txt`
echo hoge > ${now}

sudo で I/O リダイレクト

I/Oリダイレクトして root 権限が必要にファイルに書き込む

Mac で複数のファイルを一括でタイムスタンプを取得し、年月日時分秒形式に変換してファイル名にセットする

for f in *.txt; do ts=`stat -f %m $f`; dt=`date -r $ts +%Y%m%d-%H%M%S`; mv $f $dt.jpg; done

計算する

10進数計算する

expr を使う

expr 3 "*" 5

$(()) を使う

echo $((3 * 5))

bc を使う

echo “3 * 5” | bc または bc コマンドを実行して、対話的に計算式を入力

16進数 ⇔ 10進数計算する

空行を削除

文字列置換

正規表現

if の括弧はを二重に囲む([[]])
正規表現文字列をダブルクォートで囲むことはできない
\s のような文字クラスは使えない

VAR="ABC123"
if [[ $VAR =~ ^([A-z]+)([0-9]+)$ ]]; then
  echo ${BASH_REMATCH[1]}
  echo ${BASH_REMATCH[2]}
fi

スペースを含む場合は、正規表現文字列を変数にセットしてマッチング処理ができる
タブ文字を入力する場合は control + V, control + I で入力

VAR="ABC 123"
REG="^([A-z]+)[ ]*([0-9]+)$"
if [[ $VAR =~ $REG ]]; then
  echo ${BASH_REMATCH[1]}
  echo ${BASH_REMATCH[2]}
fi

ループ

10 回繰り返す

for i in {1..10}
do
    echo $i
done

または

for i in `seq 1 10`
do
    echo $i
done

変数に格納された回数繰り返す

MAX=10
for i in `seq 1 $MAX`
do
    echo $i
done

ファイルを 1行ずつ読み込んで処理する

while read line
do
    echo $line
done < readme.txt

標準入力から 1行ずつ読み込んで処理する

ls -1 | while read line; do echo $line; done

変数にセットされた複数行のカンマで区切られた文字列を順に処理する

LIST="
# comment
abc,def,efg

# comment
123,456,789
"
while IFS= read -r line; do
  # 空行を取り除く
  [[ -z "$line" ]] && continue
  # '#' で始まるコメント行を取り除く
  [[ ${line} =~ ^#.* ]] && continue
  # カンマで分割
  IFS=',' read -r var1 var2 var3 <<< "$line"
  echo "${var1}, ${var2}, ${var3}"
done <<< "${LIST}"

結果

abc, def, efg
123, 456, 789

ワンライナー(ループ内)でバッグラウンド実行する

for F in *.json; do hoge $F &; done

このようにセミコロン(;)の前に & があると「-bash: syntax error near unexpected token `;’」というエラーになる。
(解決策)
次のようにセミコロン(;)と & の間に何かコマンドを入れておく。

for F in *.json; do hoge $F & sleep 0; done

その他

shell script samples

Java