【社内勉強会】WindowsユーザのためのUnixコマンド(検索編) 2017/05/10


# 0.はじめに

------------------
## 対象者
* 普段Windowsを使っていて、Unixコマンドを使ったことがない人
* Windowsのコマンドプロンプトを使っている
    - ワイルドカード
    - リダイレクト
    - パイプライン
    
### 対象環境
* Git Bashが使える（ [Git for Windows](https://git-for-windows.github.io/) をインストール）



------------------
## 伝えたいこと

* grep, find, xargsコマンドを駆使した、検索方法
    - 影響範囲調査などの効率化


------------------
## 目次

1. Unix
2. grepコマンド
3. findコマンド
4. ファイル閲覧コマンド
5. xargsコマンド
6. 付録

------------------
# Unix


------------------
## Unixとは?
1970年代に開発されたOSの一種。


------------------
## WindowsユーザがUnixコマンドを覚えるメリット

* Windowsコマンドプロンプトより便利（PowerShellという選択肢もあるが、私は使ったことがない。。。）
* sakura editorやEclipseより詳細な検索ができる
* Windows10からbash(Unixコマンド)を利用できる



------------------
## コマンドの基礎

```bash
# ファイルの中身をcommandの標準入力に渡す
$ command < file

# commandの標準出力をファイルに書き込む
$ command > file

# [Try] Helpを表示する(Git Bashはmanコマンドがない)
$ command --help
```

------------------
# grepコマンド

------------------
## grepコマンドの概要

パターンにマッチする行を表示するコマンド。

### 使い道

* メソッド修正による影響範囲の調査
* ログの解析
* CSVファイルの解析

### 書式

```
grep [OPTIONS] PATTERN [FILE...] 
grep [OPTIONS] [-e PATTERN | -f FILE] [FILE...]  
```

[GNU grep Manual](https://linuxjm.osdn.jp/html/GNU_grep/man1/grep.1.html)
[Unix grep](http://x68000.q-e-d.net/~68user/unix/pickup?grep)

------------------
## grepコマンドの基本的な使い方

### オプション
* `-e`：パターンの指定
* `-f`：ファイルの指定
* `-i`：大文字小文字区別しない
* `-v`：マッチしない行を表示
* `-n`：行番号表示

### Let's Try

```bash
$ grep -e "aichi" grep1.txt
$ grep -e "aichi" -v -n  grep1.txt
$ # OR検索(AND検索は後述)
$ grep -e "aichi" -e "gifu"  grep1.txt
```


------------------
## 正規表現に関する検索

### オプション
* `-G`：基本正規表現として検索。デフォルト
* `-E`：拡張正規表現として検索
* `-F`：固定文字列として検索


### 基本正規表現(BRE)と拡張正規表現(ERE)
EREは現代の基本的な正規表現。
量指定子の`?`や`+`が使える


### Let's Try

```bash
$ grep -e "a+" grep3.txt
$ grep -E -e "a+" grep3.txt
$ grep -F -e "a+" grep3.txt
```

------------------
## 前後の文脈行の制御

### オプション

* `-A NUM`：NUM で指定した行数だけ、マッチした行の後を表示
* `-B NUM`：NUM で指定した行数だけ、マッチした行の前を表示

下記ファイルのように、数行単位でまとまっているファイルの調査に便利。

```txt:grep2.txt
name:aichi
population:100
name:gifu
population:200
name:AICHI
population:200
```

### Let's Try

```bash
$ grep -E "aichi" -i -A 1 grep2.txt
```


------------------
## 複数ファイルの検索

### オプション

* `-r`：再帰的に検索（このオプションを指定しないと、カレントディレクトリのみを検索）

### Let's Try

```bash
$ grep -E "aichi" grep1.txt grep2.txt
$ grep -E "aichi" grep*.txt
```



------------------
## [補足]日本語検索

Git Bashのデフォルト文字コードはUTF-8。
ファイルがUTF-8で保存されていれば、日本語で検索可能。

Git Bashで文字コードを変える方法は分からない。。。




------------------
# findコマンド



------------------
## findコマンドの概要

ファイルを再帰的に検索するコマンド。
名前だけでなく、更新日やファイルサイズで検索可能。

### 使い道

* ファイルの登録確認
* 不要なファイルの検索
     - 空ファイル、空フォルダ
     - 修正日が1年以上前のファイル

### 書式

```
find  [path...] [expression]  
```

[GNU find Manual](https://linuxjm.osdn.jp/html/GNU_findutils/man1/find.1.html)
[Unix find](http://x68000.q-e-d.net/~68user/unix/pickup?find)

------------------
## findコマンドの基本的な使い方

### オプション

* `-name`：ファイル名、ディレクトリ名を検索
* `-iname`：`-name`の大文字小文字区別しない版
* `-regex`：正規表現で検索
* `-iregex`：`-regex`の大文字小文字区別しない版


### Let's Try

```bash
$ find . -name "grep*.txt"
```


------------------
## 名前以外で検索

### オプション

* `-size n`：ファイルサイズを指定.`+`でn以上、`-`でn以下を表す。
* `-type`：ファイルの種類を指定
    - `d`：ディレクトリ
    - `f`：ファイル
    - `l`：シンボリックリンク
* `-mtime n`：n日前に修正されたファイルを検索
* `-empty`：空ファイル or 空ディレクトリ
* `-maxdepth n`：検索対象を n 階層に制限する
* `-prune`：それ以上ディレクトリを降りない。ディレクトリを除外するときに利用する。

### Let's Try

```bash
# 1KByte以上のファイル
$ find . -size 1k
# 1日前に修正されたファイルを検索(AND検索)
$ find . -mtime 1 -type f
# 拡張子がtxt OR ディレクトリを検索(AND検索)
$ find . -name "*.txt" -or -type d
```

### 誰か教えて！
n日前でなく、YYYYMMDD日より前、後で検索する方法を、誰か教えて！



------------------
# ファイル閲覧コマンド


------------------
## lessコマンド

テキストファイルを1ページずつ表示するコマンド。
Git Bash上でファイルを閲覧することが可能。

### 操作コマンド
* SPACE：１ページ進む
* b：1ページ戻る
* /[パターン]：現在位置からパターン検索をし、移動する
    - n：検索を再実行する
    - N：逆方向に検索を再実行する


```bash
$ less grep_help.txt
```

[Unix less](https://www.k-tanaka.net/unix/less.php)

------------------
## [補足] tail, headコマンド

ファイルの末尾/先頭を表示するコマンド。
大容量のファイル(ログファイルなど)を確認するのに便利。


### tail, headの共通オプション
`-n`：指定した行数表示



------------------
# xargsコマンド




------------------
## xargsコマンドの前にパイプの説明

パイプとは、command1の標準出力をcommand2の標準入力に渡す方法。

```bash
command1 | command2
```

### Let's Try

```bash
# 検索結果をlessコマンドで表示(検索結果が大量のときに便利)
$ grep -e "aichi" grep1.txt | less
# 検索結果の行数を表示(`wc -l`で行数を表示できる)
$ grep -e "aichi" -i grep1.txt | wc -l
# grepのAND検索
$ grep -e "aichi" grep1.txt | grep -e "100"
```



------------------
## xargsの概要

標準入力から引数を読み込み、指定のコマンドを実行する。

### 書式


[Unix xargs](http://x68000.q-e-d.net/~68user/unix/pickup?xargs)

------------------
## xargsの基本的な使い方

findコマンドとの組み合わせることが多い。

## 具体的な使い方
* 大量のあるログファイルの中から、exceptionが発生していない確認
* あるフォルダのみ除外したファイル検索結果から、grep検索

```bash
$ find . -name "grep*.txt" | xargs grep -e "aichi"
# 半角スペースを含むファイルに該当する際は、区切り文字を改行にする
$ find . -name "*.txt" | xargs -d "\n" grep -e "aichi"
```

------------------
## xargsの応用的な使い方(作成中)


------------------
# 付録


------------------
## 参考図書

[Linuxコマンド ビギナーズブック ](https://www.amazon.co.jp/Linux%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89-%E3%83%93%E3%82%AE%E3%83%8A%E3%83%BC%E3%82%BA%E3%83%96%E3%83%83%E3%82%AF-%E5%A4%A7%E6%B4%A5-%E7%9C%9F/dp/4798114022)

2007年発行で、お薦めではない。
大学時代に買って、1個ずつコマンドを試した思い入れのある本。
大学時代を懐かしむ用。

------------------
## おすすめ？

[まんがでわかるLinux シス管系女子](https://www.amazon.co.jp/product-reviews/4822224961/ref=cm_cr_arp_d_paging_btm_3?ie=UTF8&reviewerType=all_reviews&showViewpoints=0&sortBy=recent&pageNumber=3#RFSRI883OAY3B)

漫画だけど、結構詳しい。
どちらかというと、愛でる用。


------------------
## LPIC

Linux Professional Institute Certificationの略。
Linux技術者の技術者認定資格の名称

------------------
## Git Bashにインストールした方がよさそうなコマンド

* [manコマンド](http://neos21.hatenablog.com/entry/2016/07/20/000000)
* [nkfコマンド](https://mag.osdn.jp/09/02/12/0530242)