改めてLinuxコマンドを理解する [grep編]

## はじめに
こんにちは！ITスクールRareTECHにてCS（Customer Support）を担当している池村です。今回の記事はLinuxの`grep`コマンドについてです。

個人的に`find`と`grep`のコマンドは正規表現と呼ばれる手段を使って使用されることが多く、初学者には難しいです。でもやりたいことはわかっているので、まずはこのコマンドが何をするコマンドなのかをしっかり押さえていきましょう。

![b5a84825-72ce-420e-b16b-5c2604f8d099_720.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3798971/8471694b-0870-55c4-475e-a5f579523227.png)



## `grep`コマンドとは？
`grep`コマンドは、ファイルの中身や、他のLinuxコマンドの実行結果の中から特定の文字列が含まれる行だけを抜き取って表示させるコマンドです。

上記の説明を読んでも？となると思いますので、以下のコマンドを私のPCのホームディレクトリで実行してみます。
```Bash:grepコマンドの簡単な使用例
ls | grep "Do"
```
実行結果は以下になります。普通に`ls`した結果についても一緒に共有します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3798971/bd93acd1-f744-3b4e-49eb-08cb624f55d2.png)

これは簡単に言いますと、`ls`コマンドの結果の中から、『Do』という文字列が含まれているものだけを抽出しています。これだけ見ると、それほど難しくありませんね。
『Do』が含まれているのは『Documents』と『Downloads』だけでした。



では次にテキストファイルの中から特定の文字列が含まれている部分を切り出してみます。
今回は以下の文章が書かれた`test.txt`とういうファイルを用意します。
```Bash:test.txtの中身
むかし、むかし、ある所におじいさんとおばあさんが住んでいました。
おじいさんは山へしば刈りに、おばあさんは川へ洗濯に行きました。
おばあさんが川で洗濯をしていると大きな桃が流れてきました。
「なんと大きな桃じゃろう！家に持って帰ろう。」
とおばあさんは背中に担いで家に帰り、その桃を切ろうとすると、なんと桃から大きな赤ん坊が出てきたのです。
「おっとたまげた。」
二人は驚いたけれども、とても喜び、
「何という名前にしましょうか。」
「桃から生まれたから、桃太郎というのはどうだろう。」
「それがいい。」
桃太郎はあっと言う間に大きくなり、立派な優しい男の子になりました。
```

では上記の文章の中から特定の文字列の入った行だけを取り出してみます。
```Bash:grepでファイルの中身から抜き出す
grep "おばあさん" test.txt
```
この実行結果は以下になります。
```Bash:実行結果
むかし、むかし、ある所におじいさんとおばあさんが住んでいました。
おじいさんは山へしば刈りに、おばあさんは川へ洗濯に行きました。
おばあさんが川で洗濯をしていると大きな桃が流れてきました。
とおばあさんは背中に担いで家に帰り、その桃を切ろうとすると、なんと桃から大きな赤ん坊が出てきたのです。
```
おばあさんという文字列を含む行だけを抜き出すことができました。

もちろん、複数の文字列を指定して抜き出すことも可能です。

```Bash:書き方
grep -E "おじいさん|おばあさん" test.txt
```

```Bash:実行結果
むかし、むかし、ある所におじいさんとおばあさんが住んでいました。
おじいさんは山へしば刈りに、おばあさんは川へ洗濯に行きました。
おばあさんが川で洗濯をしていると大きな桃が流れてきました。
とおばあさんは背中に担いで家に帰り、その桃を切ろうとすると、なんと桃から大きな赤ん坊が出てきたのです。
```

## 特定のディレクトリの中から検索してみる
ファイルの中、コマンドの実行結果から抜き出しが終わったので、今度はディレクトリ以下のファイル群などから特定のものだけを抜き出してみます。

今回の環境は以下です。
```Bash:書き方
.
├── test.py
├── test.txt
└── test2
    ├── error.log
    ├── error.txt
    ├── test.csv
    └── test.go
```

もし同じ環境を作るときは以下のコマンドでどうぞ。
```Bash:環境構築
mkdir -p test2 && touch test.py test.txt test2/error.log test2/error.txt test2/test.csv test2/test.go && echo 'error message' >> test2/error.log
```

では実際に文字列検索してみましょう。
```Bash:grep使用
grep "error" test2/*
```

```Bash:実行結果
test2/error.log:error message
```

無事抜き出すことができました。ディレクトリの中のファイルの中から特定の文字列が入っているファイルだけを抜き出しています。
ここで出てきている`*`は正規表現の一種です。次の項目ではこれを使った検索方法をいくつかみていきましょう。

:::note warn
あくまでファイルの中の文字列を検索しているため、中身に何も書かれていないと検索結果は表示されません。今回の場合、ファイル名にerrorという文字列が入っていても、中身に書かれていないと表示されないのでご注意ください。
:::


## 正規表現
正規表現を使った文字列検索を見ていきましょう。
今回はまた`test.txt`を使っていきます。桃太郎の冒頭の文章が書かれたものですね。
基本的に正規表現を使うときはオプションの`-E`を使います。
### `$`（行末）
行末がこれで終わりますよ〜という時に使う正規表現です。
例えば以下です。
```Bash:$の使い方
grep -E "ました。$" test.txt
```
```Bash:実行結果
むかし、むかし、ある所におじいさんとおばあさんが住んでいました。
おじいさんは山へしば刈りに、おばあさんは川へ洗濯に行きました。
おばあさんが川で洗濯をしていると大きな桃が流れてきました。
桃太郎はあっと言う間に大きくなり、立派な優しい男の子になりました。
```
今回の場合、〜ました。という行末になっている行だけを取り出しています。

### `^`（行頭）
今度は行頭です。
例えば以下です。
```Bash:^の使い方
grep "^お" test.txt
```
```Bash:実行結果
おじいさんは山へしば刈りに、おばあさんは川へ洗濯に行きました。
おばあさんが川で洗濯をしていると大きな桃が流れてきました。
```

### `[]`（いずれかを含む）
今度は文字や数字の範囲内でそのいずれかを含む場合で検索する、を見ていきます。
```Bash:[]の使い方
grep "[0-9]" test.txt
```

上記の指定の場合、数字の0~9までのどれかの数字を含んでいる行を表示します。
今回はファイルの中の適当な行に数字を一つ入れてみました。
```Bash:実行結果
「それがいい。」1
```
もちろんこれは数字だけでなく、アルファベットなどの範囲`[a-z]`や`[A-Z]`など細かく指定ができます。

### `.`（任意の1文字）
`.`（ドット）は、文字列の中の1文字を検索したい時に使います。
```Bash:.の使い方
grep "お." test.txt
```
この場合の検索結果は以下になります。
```Bash:検索結果
むかし、むかし、ある所におじいさんとおばあさんが住んでいました。
おじいさんは山へしば刈りに、おばあさんは川へ洗濯に行きました。
おばあさんが川で洗濯をしていると大きな桃が流れてきました。
とおばあさんは背中に担いで家に帰り、その桃を切ろうとすると、なんと桃から大きな赤ん坊が出てきたのです。
「おっとたまげた。」
```
『お◯』になる文字列がある部分を全て持ってきています。
『おじいさん』、『おばあさん』はもちろん、『おっと』も持ってきていますね。

### `*`（直前の文字が0回以上繰り返される）
次に紹介するのは`*`（アスタリスク）を使った検索方法です。
```Bash:*の使い方
grep "むかし.*所" test.txt
```

```Bash:実行結果
むかし、むかし、ある所におじいさんとおばあさんが住んでいました。
```
この使い方だと、『むかし』と『所』の間に任意の文字が0回以上繰り返されている部分を抜き出してくれます。

:::note info
`*`はfindコマンドでも多用するので、しっかり覚えていきたいです。
:::


## おわりに
今回はgrepコマンドの使い方について記事にさせていただきました。
様々なコマンドと組み合わせて使うコマンド、という印象が強いです。
正規表現は私自身使いこなしているわけではないですが、今回記事にしたところくらいはある程度覚えておいています。でも最近はAIに聞いた方が早いですね。無理して覚える必要はない気もしています。


まとめ記事に戻るにはこちら👇

https://qiita.com/ikemura-ren/items/3e7b6ec1b0cd9b3928d6