zshのhistoryを使いこなす

zshのhistoryの使い方調べたんで共有します。

# 最初に注意事項
oh-my-zshを使ってたら勝手に`alias history='fc -l 1'`されちゃうので、`unalias history`しないと以下で紹介するやつが動きません。

# 実行日時を表示する
`-i`オプションで表示出来ます。

```
$ history -i
 8471  2013-12-23 19:32  unalias history
 8472  2013-12-23 19:32  history
 8473  2013-12-23 19:32  which history
 8474  2013-12-23 19:32  bash
 8475  2013-12-23 19:33  man zshbuiltins
 8476  2013-12-23 19:35  history -100
 8477  2013-12-23 19:35  which history
 8478  2013-12-23 19:35  history -D
 8479  2013-12-23 19:36  history -iD
 8480  2013-12-23 19:37  msg
 8481  2013-12-23 19:37  zsh --version
 8482  2013-12-23 19:38  bindkey
 8483  2013-12-23 19:39  bindkey | grep -i '^r'
 8484  2013-12-23 19:39  bindkey | grep -i 'search'
 8485* 2013-12-23 19:41  msg
 8486  2013-12-23 20:34  history -D
```

# 実行にかかった時間を表示する
`-D`オプションで表示できます。

```
$ history -D
 8472  0:00  history
 8473  0:00  which history
 8474  0:09  bash
 8475  1:41  man zshbuiltins
 8476  0:00  history -100
 8477  0:00  which history
 8478  0:00  history -D
 8479  0:00  history -iD
 8480  0:22  msg
 8481  0:00  zsh --version
 8482  0:00  bindkey
 8483  0:00  bindkey | grep -i '^r'
 8484  0:00  bindkey | grep -i 'search'
 8485* 0:00  msg
 8486  0:00  history -D
 8487  0:00  history -i
```

もちろんオプションは組み合わせて使えます。

```
$ history -Di
 8473  2013-12-23 19:32  0:00  which history
 8474  2013-12-23 19:32  0:09  bash
 8475  2013-12-23 19:33  1:41  man zshbuiltins
 8476  2013-12-23 19:35  0:00  history -100
 8477  2013-12-23 19:35  0:00  which history
 8478  2013-12-23 19:35  0:00  history -D
 8479  2013-12-23 19:36  0:00  history -iD
 8480  2013-12-23 19:37  0:22  msg
 8481  2013-12-23 19:37  0:00  zsh --version
 8482  2013-12-23 19:38  0:00  bindkey
 8483  2013-12-23 19:39  0:00  bindkey | grep -i '^r'
 8484  2013-12-23 19:39  0:00  bindkey | grep -i 'search'
 8485* 2013-12-23 19:41  0:00  msg
 8486  2013-12-23 20:34  0:00  history -D
 8487  2013-12-23 20:34  0:00  history -i
 8488  2013-12-23 20:35  0:00  history -D
```

# 範囲を指定して表示する
historyはデフォルトでは直近16件表示されますが、この表示する範囲を指定することが出来ます。
`history first last`の形式で、`first`から`last`まで表示します。`last`が無ければ最後まで表示します。
と、言葉で説明するよりも例を見せるほうが分かりやすいと思うので、例を書くと

```
# 説明用にコマンドをecho 1からecho 20まで実行した履歴の状態を作った
$ history # デフォルトは直近16件
    5  echo 5
    6  echo 6
    7  echo 7
    8  echo 8
    9  echo 9
   10  echo 10
   11  echo 11
   12  echo 12
   13  echo 13
   14  echo 14
   15  echo 15
   16  echo 16
   17  echo 17
   18  echo 18
   19  echo 19
   20  echo 20
$ history -5 # 直近5件表示
   17  echo 17
   18  echo 18
   19  echo 19
   20  echo 20
   21  history
$ history 1 # 履歴の1番目から全て表示（要は全て表示）
    1  echo 1
    2  echo 2
    3  echo 3
    4  echo 4
    5  echo 5
    6  echo 6
    7  echo 7
    8  echo 8
    9  echo 9
   10  echo 10
   11  echo 11
   12  echo 12
   13  echo 13
   14  echo 14
   15  echo 15
   16  echo 16
   17  echo 17
   18  echo 18
   19  echo 19
   20  echo 20
   21  history
   22  history -5
$ history 1 5 # 履歴の1番目から5番目まで表示
    1  echo 1
    2  echo 2
    3  echo 3
    4  echo 4
    5  echo 5
$ history -10 -5 # 履歴の直近10件目から直近5件目まで表示
   15  echo 15
   16  echo 16
   17  echo 17
   18  echo 18
   19  echo 19
   20  echo 20
```

# パターンマッチで絞り込む
`-m`オプションで`history | grep hoge`的なことが出来ます。<del>じゃあgrepでいいやん</del>
`-m`オプションは部分一致ではなく完全一致で検索され、ワイルドカードが使えます。
また、検索する範囲は前項の表示する範囲に従います。
例によって文章で書くよりも例のが分かりやすいと思うので例をば

```
$ history -m 'man *' # 直近のコマンド16件のうちmanコマンドを使ったやつを表示
 8572  man zshbuiltins
$ history -m 'man *' 1 # 履歴全体からmanコマンド使ったやつを表示
  237  man emacs
  276  man fg
...略...
$ history -m '*zsh*' 1 # 履歴全体からzshを含むコマンドを表示
    6  less .zshrc
    7  rm .zshrc
...略...
$ history -m 'man zshparam' 1 # 履歴全体から'man zshparam'と完全一致するコマンドを表示
 1395  man zshparam
 5562  man zshparam
 5573  man zshparam
```

と言う感じ。
最後のは完全一致で絞り込んだところで意味が無いように思えますが、例えば`-i`オプションと組み合わせるといつそのコマンドを実行したかがわかるので、意味が無いこたないです。

```
$ history -im 'man zshparam' 1
 1395  2012-12-23 01:13  man zshparam
 5562  2013-10-10 00:40  man zshparam
 5573  2013-10-10 01:32  man zshparam
```

# 終わりに
zshのhistoryには他にも機能はあるので、興味がある人は`man zshbuiltins`して`fc`の項目を見てみてください。なぜ`history`の項目ではないのかは`history`の項目を見てみるとすぐ分かるんですが、

```
       history
              Same as fc -l.
```

となってます。つまり`history`は`fc -l`だったんですね！ほぼaliasのようなものみたいです。
例えば範囲指定で存在しないところを指定すると

```
$ history 1000000
fc: no such event: 1000000
```

と表示されます。内部で`fc`を使っていてそのエラーメッセージをそのまま表示してるらしいです。