grepでこういう時はどうする?

文字列を抽出するときも、抽出除外するときも便利なGREP、LinuxでCUI操作をするには無くてはならない存在です
ほとんど抽出にしか使いませんが、多少覚え書きがありましたので共有しておきます

- よく使う使い方

```
grep 検索したい文字列 検索したいテキストファイル

コマンド | grep 検索したい文字列

grep -e 検索したい文字列1 -e 検索したい文字列2 検索したいテキストファイル

grep -i 検索したい文字列 検索したいテキストファイル
```

- 正規表現を使う

```
grep -E '正規表現' source.txt

#利用できる正規表現

.                    改行文字以外の任意の1文字
*                    直前の1文字の0回以上の繰り返しに一致。直前の文字は正規表現でも構わない
^                    行の先頭
$                    行の末尾
[ ]                  かっこ内の任意の1文字に一致。ハイフン（-）で範囲指定もできる
[^ ]                 かっこ内の任意の1文字に不一致。ハイフン（-）で範囲指定もできる
\+                   直前の文字の1個以上の繰り返しに一致
\?                   直前の文字の0または1文字に一致
\{n\}                直前の文字のn個の繰り返しに一致
\{n,\}               直前の文字のn個以上の繰り返しに一致
\{,m\}               直前の文字のm個以下の繰り返しに一致
\{n,m\}              直前の文字のn個以上，m個以下の繰り返しに一致
pattern1\|pattern2   pattern1またはpattern2のいずれかに一致
\(pattern\)          patternをグループ化する。マッチした内容は\numで参照できる
\                    正規表現に使われる記号を普通の文字として扱う

例
grep '\[0-9]' source.txt                           # '[0-9]'の文字列を検索
grep -E '(\[0-9]){2}' source.txt                   # '[0-9]'が2回続く文字列を検索
grep '[Ll]inux' source.txt                         # 「Linux」または「linux」が含む行を検索する
grep '\<[Ll]inux\>' source.txt                     #  独立した「Linux」または「linux」が含む行を検索する、RedhatLinuxとかは含まない
grep '[1-9][0-9][0-9][A-Z][0-9]' source.txt        # 先頭に0を含まず123A7のようなパターンに一致
grep '^[0-9]' source.txt                           # 数字を含まない行を検索する
grep '.....' source.txt                            # 5文字以上の行だけ探す
grep '\<W...s\>$' source.txt                       # 先頭がW、末尾がsの文字列を探す
grep '.' source.txt                                # 空行を除外
grep '^\<EX\>\{1,3\}' source.txt                   # EXという文字が1～3回出る行
grep '\<[A-Z]\{\6,15\}\>' source.txt               # 大文字アルファベットが6～15文字含む行
grep '\<[A-Za-z]\{\6,15\}\>' source.txt            # 大文字小文字アルファベットが6～15文字含む行
grep '\<[^0-9A-Za-z]\{\6,15\}\>' source.txt        # 大文字小文字アルファベットと数字以外の文字が6～15文字含む行
grep '[0-9]\{3\}-[0-9]\{3\}-[0-9]\{4\}' source.txt # 電話番号000-000-0000を含む行
```

- フォルダ内のファイルを再帰的に指定し"パターン"を見つけたら行番号をつけて表示

```
grep -rn 'パターン' *
```

- アクセスログをリアルタイムに表示する

```
tail -f access_log | grep --line-buffered 'パターン'
```

- if文の条件にする

```
if grep 'パターン' "ファイル" >/dev/null; then
    echo "パターンが含まれています"
else
    echo "パターンが含まれていません"
fi
```

- 標準入力から見つける場合は

```
if echo "$STR" | grep 'パターン' >/dev/null; then
    echo "パターンが含まれています"
else
    echo "パターンが含まれていません"
fi
```

-マッチした行の前後数行を表示する

```
#関連オプション
-B, --before-context=NUM  一致した前の NUM 行を表示する
-A, --after-context=NUM   一致した後の NUM 行を表示する
-C, --context=NUM         一致した前後 NUM 行を表示する

# マッチした行とその前5行、後ろ3行を表示
grep -A3 -B5 banana thing.txt
```

- 複数のパターンで検索する

```
grep -E 'パターン1|パターン2' source.txt
```

- 大文字小文字区別せずに検索する

```
grep -i 'パターン' source.txt
```

- 行頭または行末に限定してパターンを検索する

```
#行頭に#がついている行だけ
grep '^#' source.txt
cat /etc/my.cnf | grep '^#' 

#行末にlogがついている行だけ
grep 'log$' source.txt
cat /etc/my.cnf | grep 'log$'
```

- ハイライトをつける

```
grep --color=always 'パターン' source.txt
```

- パターンを除外して表示

```
grep -v 'パターン' source.txt

#たとえばps auxをした際
ps aux | grep java
#とすると"grep java"自体もヒットしてしまうが
ps aux | grep java | grep -v grep
#とすれば、grep自体は引っ掛からない
```

- パータンの出現行数を数える

```
grep -c 'パターン' source.txt
```

- 独立パターンだけ抽出

```
grep -w 'パターン' source.txt

#たとえば
grep -w 'if' source.txt
#とやると、elseifやendif、iftopなどifを含むものは引っ掛からず、" if "と独立しているモノだけ引っ掛かる
```