Bashのコマンド履歴にまつわるエトセトラ

## はじめに

Bashで過去に入力したコマンドを呼び出すのに、`↑`や`Ctrl+p`などを利用していると、なかなか目的のコマンドに辿り着かず「あぁーーーー、もうっ!!」ってなることありませんか? (私はしょっちゅうなってます。)
そんなモンモンとしている日々をスカッと解決させる小技紹介です。

個人的にはインクリメンタルサーチ最強。

## コマンド履歴の順次呼び出し

言わずとも知れた`↑``↓`入力でひとつ前、ひとつ先のコマンドを順々に呼び出せます。
おなじことは`Ctrl+p``Ctrl+n`でも可能です。こっちの方がホームポジションから右手が動かないから便利かも。

## 履歴番号指定のコマンド呼び出し

入力したコマンドの履歴一覧は`history`コマンドで表示できます。
ここから目的のコマンドをコピペして実行...ではなく、履歴番号を指定してコマンド実行することができます。

```bash
[tasaki-no-MacBook-Air@d-tasaki:~]
$ history | tail
 9964  2015-02-07T20:50:07+0900 grep -nr expires_at app/ | grep device
 9965  2015-02-07T21:13:41+0900 grep -nr active_time app/
 9966  2015-02-07T21:21:08+0900 grep -nr ver app/
 9967  2015-02-07T21:23:22+0900 grep -nr -e "api.*_commands_check" app/
 9968  2015-02-07T20:09:17+0900 ssh dev-csam-web
 9969  2015-02-09T09:06:26+0900 curl -s -o /dev/null "https://www.yahoo.co.jp/"
 9970  2015-02-09T09:30:32+0900 ssh PROD-clomo-web
 9971  2015-02-09T11:07:20+0900 ls
 9972  2015-02-09T11:13:53+0900 vi /tmp/foo.xml
 9973  2015-02-09T11:16:46+0900 vi /tmp/auth.xml
　#↑これが履歴番号

[tasaki-no-MacBook-Air@d-tasaki:~]
$ !9970
ssh PROD-clomo-web  # ← 9970番のコマンドを実行!
Last login: Mon Feb  9 11:50:45 2015 from 211.5.66.72
[ec2-user@CLOMO-WEB ~]#
```

なお、お尻に`:p`を入力するとコマンドを実行するのではなく、表示だけしてくれます。

```bash
[tasaki-no-MacBook-Air@d-tasaki:~]
$ !9970:p
ssh PROD-clomo-web  # ← 9970番のコマンドを表示のみ
[tasaki-no-MacBook-Air@d-tasaki:~]
$ 
```

この状態で`↑`や`Ctrl-p`を押すと、さっき表示させたコマンドが一番目に出てきますので、適宜コマンドを修正して実行させることができます。


## 直前のコマンド実行

直前のコマンドであれば、`!!`とすることで実行させられます。

```bash
[tasaki-no-MacBook-Air@d-tasaki:~]
$ less /usr/nginx/conf.d/nginx.conf

[tasaki-no-MacBook-Air@d-tasaki:~]
$ !! # ← 直前に実行したコマンドを実行
```

これもお尻に`:p`を指定することで表示のみさせることができます。

## 直前のコマンドの置換

`^foo^bar`のように入力すると直前コマンドの`foo`を`bar`に置き換えたコマンドを実行することができます。

```bash
[tasaki-no-MacBook-Air@d-tasaki:~]
$ grep "Command" production.log-20150206

[tasaki-no-MacBook-Air@d-tasaki:~]
$ ^06^07
grep "Command" production.log-20150207
```

## インクリメンタルサーチ

過去に入力したあのコマンドをもう一回実行したい、という場合は大抵『あのコマンド』というのが頭に浮かんでいるはずです。『あのコマンド』の一部だけでもいいので直接入力して検索できたらステキじゃないですか。しかも入力文字列が増えていったらどんどん絞り込みされていったらさらにステキじゃないですか。
それができるのがインクリメンタルサーチです。

コンソールにて`Ctrl+r`を押すとコマンド履歴をインクリメンタルに検索するモードになります。
適当に文字列を入力して`Ctrl+r`を繰り返していけば目的のコマンドまで簡単に到達できます。

例えば、過去に入力した`git pull`コマンド履歴を探したい場合は下記のような操作になります。

```bash
[tasaki-no-MacBook-Air@d-tasaki:api] (dev-1-customize_for_clomo2.1)
$ 

 ↓ Ctrl+rを入力

[tasaki-no-MacBook-Air@d-tasaki:api] (dev-1-customize_for_clomo2.1)
(reverse-i-search)`': 

 ↓ 「g」と入力

[tasaki-no-MacBook-Air@d-tasaki:api] (dev-1-customize_for_clomo2.1)
(reverse-i-search)`g': grep -nr Capistrano::Git vendor/bundle/ruby/2.1.0/gems/capistrano-3.1.0/lib/

 ↓ 「i」と入力

[tasaki-no-MacBook-Air@d-tasaki:api] (dev-1-customize_for_clomo2.1)
(reverse-i-search)`gi': aws ec2 describe-instances  | jq '.Reservations[].Instances[] | {InstanceId, PublicIpAddress, PrivateIpAddress, InstanceName: (.Tags[] | select(.Key=="Name").Value), KeyName, Status: (.State | {Name})}'

 ↓ 「t」と入力

[tasaki-no-MacBook-Air@d-tasaki:api] (dev-1-customize_for_clomo2.1)
(reverse-i-search)`git': git push origin `git rev-parse --abbrev-ref HEAD`

 ↓ Ctrl+rを2回入力

[tasaki-no-MacBook-Air@d-tasaki:api] (dev-1-customize_for_clomo2.1)
(reverse-i-search)`git': git commit

 ↓ 「pull」と入力

[tasaki-no-MacBook-Air@d-tasaki:api] (dev-1-customize_for_clomo2.1)
(reverse-i-search)`git pull': git pull origin `git rev-parse --abbrev-ref HEAD`

 ※ 目的のコマンドが表示されたのでEnterを入力してコマンド実行!

```