よく使うbashのコード

## よく使うbashコード

### ■ 部分文字列を抽出する

参考）https://qiita.com/koara-local/items/04d3efd1031ea62d8db5

```bash:指定方法
${パラメータ:オフセット:長さ}
```

```bash:サンプル
#!/bin/bash

## オフセットと長さを指定して文字列を取得する

HOGE="abcdef"

# オフセット位置から長さ分を取得
echo ${HOGE:0:2}
# -> ab

echo ${HOGE:2:2}
# -> cd

echo ${HOGE:4:2}
# -> ef

# 長さを省略した場合はオフセットから最後まで出力
echo ${HOGE:2}
# -> cdef

# 長さにマイナスを指定した場合は最後からマイナス分引いた位置までの長さになる
echo ${HOGE:0:-2}
# -> abcd

# 指定した変数が空文字列の場合は右に指定した文字が入る
echo ${HOGE:-2}
# -> abcdef


## `%`, `%%` 右端からの(最短の|最長の)パターン一致までを除外

HOGE=hoge.tar.bz2

echo ${HOGE}
# -> hoge.tar.bz2

# 最短除外
echo ${HOGE%.*}
# -> hoge.tar

# 最長除外
echo ${HOGE%%.*}
# -> hoge



#, ## 左端からの(最短の|最長の)パターン一致までを除外

HOGE=/home/user/hoge

echo ${HOGE}
# -> /home/user/hoge

# 最短除外
echo ${HOGE#*/}
# -> home/user/hoge

# 最長除外
echo ${HOGE##*/}
# -> hoge
```

### ■ 文字長を調べる
```bash:指定方法
${#変数名}
```

```bash:サンプル
HOGE="abcdef"
echo ${#HOGE}
# -> 6
```

### ■ 変数にある文字列が含まれているか調べる方法
```bash:サンプル
#!/bin/bash

## 200の文字が含まれるかどうか調べる
ret="HTTP/1.1 200 OK"
if [ "`echo $ret | grep '200'`" ]; then
  echo "含まれる"
fi

## 等しいかどうか調べる
ret="HTTP/1.1 200 OK"
if [ "$ret" = "HTTP/1.1 200 OK" ]; then
  echo "含まれる"
fi
```

### ■ 変数にある文字列が何回出現するか調べる方法
```bash:サンプル
#!/bin/bash

## 「.」が何回出現するか調べる
pos=`echo "abc.def.ghi.jkl" | sed -e 's@[^.]@@g' `
echo ${#pos}

## wcを使う方法
echo -n "abc.def.ghi.jkl" | sed -e 's@[^.]@@g' | wc -c
```

### ■ 変数内の文字列を置換する
参考）https://qiita.com/aosho235/items/c36568830a8d47288284

```bash:コマンド
## 文字列先頭の最短マッチ部分を削除
${変数#パターン}

## 文字列先頭の最長マッチ部分を削除
${変数##パターン}

## 文字列末尾の最短マッチ部分を削除
${変数%パターン}

## 文字列末尾の最長マッチ部分を削除
${変数%%パターン}

## 最初にマッチしたもののみ文字列を置換
${変数/検索文字列/置換文字列}

## 全ての文字列を置換
${変数//検索文字列/置換文字列}

```

### ■ ファイル内の文字列をまとめて置換する
```bash:コマンド
$ grep -l '置換対象の文字列' 置換対象のファイル | xargs sed -i.bak -e 's/置換対象の文字列/置換後の文字列/g'
```

### ■ スクリプトの絶対パスを取得

参考）https://qiita.com/koara-local/items/2d67c0964188bba39e29

```bash:サンプル
#!/bin/bash

###########
# $0 で実行コマンドを取得
# dirname でベースディレクトリを取得
# サブシェル内で cd で移動
# pwd で絶対パスの取得
###########

SCRIPT_DIR=$(cd $(dirname $0); pwd)
echo $SCRIPT_DIR

## 実行スクリプトディレクトリの親の親の親の親を取得
#- 実行スクリプトのディレクトリ
SCRIPT_DIR=$(cd $(dirname $0); pwd)
#- 実行スクリプトのディレクトリの親
dirname $SCRIPT_DIR
#- 実行スクリプトのディレクトリの親の親
dirname $(dirname $SCRIPT_DIR)
#- 実行スクリプトのディレクトリの親の親の親
dirname $(dirname $(dirname $SCRIPT_DIR))
#- 実行スクリプトのディレクトリの親の親の親の親
dirname $(dirname $(dirname $(dirname $SCRIPT_DIR)))

#- 変数に代入
APPDIR=$(cd $(dirname $(dirname $(dirname $(dirname $SCRIPT_DIR)))); pwd)
```

### ■ 一定回数繰り返す
参考) http://www.koikikukan.com/archives/2014/03/03-015555.php

```bash:サンプル
#!/bin/bash

# 初期値・ループ条件・ループ時の処理で指定する
for ((i=0; i<10; i++)); do
  #...
done

# inを利用する
for key in aaaa bbbb cccc; do
  #...
done

for file in `ls`;
do
  echo $file
done

# 値を範囲で指定する
for i in {0..9}; do
  #...
done

for i in `seq 1 9` do
  #...
done
```


### ■ 四則演算
参考）https://qiita.com/akinomyoga/items/9761031c551d43307374

```bash:サンプル
echo $((5+2)) # 足し算、結果: 7
echo $((5-2)) # 引き算、結果: 3
echo $((5*2)) # かけ算、結果: 10
echo $((5/2)) # 割り算(端数切り捨て)、結果: 2
echo $((5%2)) # 剰り、結果: 10
```

### ■ 比較演算
参考）https://www.pasonatech.co.jp/workstyle/column/detail.html?p=7450

```bash:サンプル
if [ 20 -gt 30 ]; then
    echo “Over 30”
else
    echo “Under 30”
fi
```

| 比較演算子 | 内容 |
| -------- | --------|
| 数値1 -eq 数値2 | 数値1と数値2が等しければ真（=） |
| 数値1 -ne 数値2 | 数値1と数値2が等しくなければ真（!=、<>） |
| 数値1 -gt 数値2 | 数値1が数値2よりも大きければ真（>） |
| 数値1 -ge 数値2 | 数値1が数値2以上であれば真（>=） |
| 数値1 -lt 数値2 | 数値1が数値2よりも小さければ真（<） |


### ■ ランダムの文字を生成する
参考）https://qiita.com/Vit-Symty/items/5be5326c9db9de755184
参考）https://qiita.com/Vit-Symty/items/5be5326c9db9de755184

```bash:サンプル
## パスワードなどのよくランダムな文字列
openssl rand -base64 12 | fold -w 10 | head -1
cat /dev/urandom | base64 | fold -w 10 | head -n 1

## ランダムの英数字
cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 10 | head -n 1 | sort | uniq
```

### ■ sprintfのようなことをする
```bash:サンプル
value=1
result=$(printf "aaa%03d" $value)
```

### ■ シェルのif文でAND(OR)条件を複数指定したい
```bash:サンプル１
# ANDの場合
if [ -e /tmp/some.file -a -e /tmp/some2.file ]; then
・・・
fi

# ORの場合
if [ -e /tmp/some.file -o -e /tmp/some2.file ]; then
・・・
fi
```

```bash:サンプル２
# ANDの場合
if [ -e /tmp/some.file ] && [ -e /tmp/some2.file ] && [ -e /tmp/some3.file ]; then
・・・
fi

# ORの場合
if [ -e /tmp/some.file ] || [ -e /tmp/some2.file ] || [ -e /tmp/some3.file ]; then
・・・
fi
```
(参考) https://open-groove.net/shell/if-and-or/