Bashでよく使うコマンドまとめ


普段あまり書く機会がなく、いざ書くとき結構忘れているのでまとめておく。

if

基本構文

条件式に指定されたコマンドの終了ステータスを判定し分岐を行う。
終了ステータスが0のときは真、それ以外は偽となる。


if 条件式1 ; then
  処理1
elif 条件式2 ; then
  処理2
else
  処理3
fi

本来条件式の後のthenは次の行に記載するが、
;をつけることで条件式と同一行に記載可能。

また、elseの後はthenは不要であり、
if文を閉じるにはfiが必要。

条件式

if文での条件式の評価にはtestコマンドを使用する。
testコマンドは比較の結果を0か1の終了ステータスで返すだけで、
メッセージ出力がないため、評価に特化したコマンドとなる。
test 引数の条件式と記載することが可能であるが、
[ 引数の条件式 ] と省略して記載が可能。
以降は省略形で記載する。
また、省略時カッコと条件式の間のスペースがマストのため、要注意。

逆に言うと条件式比較ではtestコマンドを使っているにすぎないので、
testコマンド以外を使うことも可能。

testにおける条件式は文字列の比較と数値の比較で記載方法が異なる。
それぞれ別でまとめる。

数値の比較

num1は条件式左の数字(testコマンドの第一引数)、num2は右(第二引数)である。

オプション 数式的意味 何の略か
-eq num1 = num2 5 -eq 5 equal
-ne num1 ≠ num2 5 -ne 5 not equal
-lt num1 < num2 5 -lt 6 less than
-le num1 ≦ num2 5 -le 6 less than or equal
-gt num1 > num2 5 -gt 4 greater than
-ge num1 ≧ num2 5 -ge 4 greater than or equal

if [ 5 -eq 5 ] ; then
  echo "等しい"
fi

文字列の比較

文字列においては、イコールが使用される。
なお、==ではないので注意。

オプション 数式的意味
= string1 = string2 "hoge" = "fuga"
!= string1 ≠ string2 "hoge" != "fuga"
-z string1 = ""(0文字ならば真) -z string1
-n string1 ≠ ""(0文字でなければ真) -n string1

if [ "文字" = "文字" ] ; then
  echo "等しい"
fi

AND,OR条件

AND,OR条件は2つの書き方が可能。
1つ目はtestコマンドのオプションを使って記載する方法
2つ目はbashコマンドを使って記載する方法

testコマンドのオプションを使う

testコマンドのオプションなので、
ひとつの[]内に記載が可能。
ただし、ぱっとみでわからないので視認性が下がるかも。

オプション 意味
-a AND 5 -a 5
-o OR 5 -o 5

なお、優先順位は-oのほうが高いため、

[ 真 -o 偽 -a 偽 ]

の結果は真となる。
()で囲うことでグルーピングが可能だが、
その場合は必ず()をエスケープする必要がある。

bashコマンドを使う

条件式内のtest以外のbashコマンドを使用する。
具体的には以下
コマンド1 && コマンド2:1つ目の処理が成功した場合のみ、2つ目のコマンドが実行される。
コマンド1 || コマンド2:1つ目の処理が失敗した場合のみ、2つ目のコマンドが実行される。

上記のコマンド1と2をtestコマンドに置き換える形である。
[ 条件式1 ] || [ 条件式2 ]

なお、こちらの優先順位は前から評価されるため、

[ 真 ] || [ 偽 ] && [ 偽 ]

は真もしくは偽で真を判定したのち、真かつ偽の判定が実施され、
結果は偽となる。

$ [ a = a ] || [ b = bb ]  &&  [ c = cc ]; echo $?
1

逆に以下の場合は真である。

$ [ a = a ] && [ b = b ] || [ c = cc ]; echo $?
0

条件の否定

コマンド前に!をつけることで、
終了ステータスを反転させることが可能。(終了ステータスが0は1に、0以外は0にする)
!のあとは必ずスペースを入れること。

[ c = cc ]; echo $?
1
! [ c = cc ]; echo $?
0

testコマンドの引数でも可能。

[ !  c = cc ]; echo $?
0

配列

普段phpなどを書いていると、
bashの配列で,を使わないことを忘れがちなので一応メモ。

定義

空の配列を定義

array=()
$ echo "${array}"
# 何も表示されない

初期値ありの配列を定義

array=("a" "b" "c")
echo ${array[@]}
a b c
コマンドの結果を配列に格納
cd /home/hoge
ls
a.csv b.csv c

dirlist=(`ls -la /home/hoge | grep '*.csv'`)
echo ${dirlist[0]}
a.csv

値の追加

現在のarrayを入れて再定義するみたいなイメージ

array=("${array[@]}" "d")
echo ${array[@]}
a b c d

値の取得

インデックス番号を指定でOK

echo ${array[0]}
a

@で全要素表示

echo ${array[@]}
a b c d

for

基本構文

for 繰り返し条件; do
    処理
done

初期値、ループ条件、ループ時の処理

鉄板パターンも記載可能。

max=10
for ((i=0; i < $max; i++)); do
    echo $i
done

ファイルの中身を読み取り

for i in $(cat filetest.txt ); do
  echo $i
done

1
2
3
4
5
6
7
8
9

配列の中身を操作

array=(0 1 2 3 4 5 6 7 8 9)
for i in ${array[@]}; do
  echo $i
done

0
1
2
3
4
5
6
7
8
9

変数展開

シングルクォートとダブルクォート

変数などを文字列で展開するためには、
ダブルクォートを使用する。

echo "${var}"
test
"```
シングルクォートだと展開されないので注意
```bash
echo '${var}'
${var}

mysqlへ接続し、結果をファイル出力

基本

セキュリティなどでINTO OUTFILEが使えない場合、
bashからリダイレクトさせて結果を取得する。
Passを変数に入れるとセキュリティ項目の設定次第ではエラーになるので、
その場合は設定を変えるかできないなら都度入力するようにする。
SQLは2行以上記載する場合はインデントを入れるとエラーになるので注意。

結果ファイルはtsv形式で格納される。


MYSQL_HOST='AAA'
MYSQL_SCHEMA='DBname'
MYSQL_ID='UserName'
OUTPUT_FILE="test.tsv"
SQL="SELECT *
FROM test
Where age > 30 ;"

mysql -h $MYSQL_HOST -u $MYSQL_ID -p -D $MYSQL_SCHEMA > ${OUTPUT_FILE} <<EOF
${SQL}
EOF

結果を変数に格納

変数=$(コマンド)でコマンドの結果を変数に格納できる。
ただし、横方向に見ながらスペース区切りで挿入されるので、
2カラム以上を抽出する場合は使えなそう。
1カラムだけ取り出してその値をごにょごにょやるとかなら使えそう。


MYSQL_HOST='AAA'
MYSQL_SCHEMA='DBname'
MYSQL_ID='UserName'
OUTPUT_FILE="test.tsv"
SQL="SELECT *
FROM test
Where age > 30 ;"
RESULT=$(mysql -h $MYSQL_HOST -u $MYSQL_ID -p -D $MYSQL_SCHEMA <<EOF
${SQL}
EOF
)

ヒアドキュメント

文字列をプログラムに埋め込むためのもので、
改行などもそのまま埋め込まれるので、
改行が必要なコマンドや、同じコマンドが連続する際に使用する。


echo "123"
echo "123"
echo "123"
echo "ABC"
echo "DEF"
echo "GHI"

これを


cat <<EOD
123
456
789
ABC
DEF
GHI
EOD

こうできる。

レコード数の確認方法

wc -l ファイル名

タブ⇒カンマに変換

sedが便利。
grepを組み合わせれば該当フォルダをすべて置換など可能。

grep -l '\t' ./*.txt | xargs sed -i.bak -e 's/\t/,/1' 

参考

if文リファレンス
for一覧
Mysqlの結果を変数へ