GNU Bourne-Again Shell を便利に使う


またまた blog からの転載ですが。

対話シェルとして使用する *bash* (1) のコマンドライン履歴機能の便利な使い方。
*bash* (1) のコマンドライン履歴機能のうちイベント指示子、単語指示子、修飾指示子は オンラインマニュアルにも情報が少ないが、慣れると非常に便利でキータイプ量も減るので是非マスターしておきたい。
以下の文中で n、m は任意の整数、 foo、bar、baz などは任意の文字列を示す。

## 機能一覧

### イベント指示子
|記述| 機能
|:---------------|-----
|!! |直前に実行したコマンドを実行する
|!-n|n 回前に実行したコマンドを実行する
|^foo^bar|直前に実行したコマンドの foo を bar に変更して実行する
|!:s/foo/bar|直前に実行したコマンドの foo を bar に変更して実行する
|!:gs/foo/bar|直前に実行したコマンドの全ての foo を bar に変更して実行する
|!foo|foo で開始されるコマンドを実行する
|!n|	n 番目に実行されたコマンドを実行する

### 単語指示子
|記述|機能
|:---------------|-----
|!:n | 直前に実行したコマンドの n 番目の引数を取得する
|!^ | 直前に実行したコマンドの 1 番目の引数を取得する
|!$ | 直前に実行したコマンドの最後の引数を取得する
|!* | 直前に実行したコマンドの全ての引数を取得する
|!:n* | 直前に実行したコマンドの n 番目から最後までの引数を取得する
|!:n-m | 直前に実行したコマンドの n 番目から m 番目までの引数を取得する
|!:-n | 直前に実行したコマンドの最初から n 番目までの引数を取得する
|!:n- | 直前に実行したコマンドの n 番目から最後の 1 個前までの引数を取得する

### 修飾指示子
|記述|機能
|:---------------|-----
|:p | コマンドを表示のみして実行しない
|:h | パスのファイル名部分を取り除きディレクトリ名を取得する
|:t | パスのディレクトリ名部分を取り除きファイル名を取得する
|:r | ファイル名の拡張子を取り除き "." の前を取得する
|:e | ファイル名の拡張子を "." 付きで取得する

## 実例

### イベント指示子

**!!**

直前に実行したコマンドを実行する

```sh:sample
$ echo foo bar baz
foo bar baz
$ !!
echo foo bar baz
foo bar baz

```

**!-n**

n 回前に実行したコマンドを実行する (複数のコマンドを繰り返して実行する場合に便利)

```sh:sample
$ echo foo bar baz
foo bar baz
$ echo FOO BAR BAZ
FOO BAR BAZ
$ !-2
echo foo bar baz
foo bar baz
$ !-2
echo FOO BAR BAZ
FOO BAR BAZ

```

**^foo^bar**
**!:s/foo/bar**

sh:sample
直前に実行したコマンドの foo を bar に変更して実行する (下のパターンの場合 "/" は任意の文字に変更が可能)

```sh:sample
$ echo foo foo foo
foo foo foo
$ ^foo^bar
echo bar foo foo
bar foo foo
$ echo foo foo foo
foo foo foo
$ !:s/foo/bar
echo bar foo foo
bar foo foo

```

**!:gs/foo/bar**

直前に実行したコマンドの全ての foo を bar に変更して実行する ("/" は任意の文字に変更が可能)

```sh:sample
$ echo foo foo foo
foo foo foo
$ !:gs/foo/bar
echo bar bar bar
bar bar bar

```

**!foo**

foo で開始されるコマンドを実行する

```sh:sample
$ echo foo bar baz
foo bar baz
$ touch foo bar baz
$ !ec
echo foo bar baz
foo bar baz

```

**!n**

n 番目に実行されたコマンドを実行する

```sh:sample
$ echo foo bar baz
foo bar baz
$ echo FOO BAR BAZ
FOO BAR BAZ
$ !1
echo foo bar baz
foo bar baz

```

### 単語指示子

**!:n**
直前に実行したコマンドの n 番目の引数を取得する

```sh:sample
$ echo foo bar baz
foo bar baz
$ echo !:0
echo echo
echo
$ echo foo bar baz
foo bar baz
$ echo !:2
echo bar
bar

```

**!^**
直前に実行したコマンドの 1 番目の引数を取得する

```sh:sample
$ echo foo bar baz
foo bar baz
$ echo !^
echo foo
foo

```

**!$**
直前に実行したコマンドの最後の引数を取得する

```sh:sample
$ echo foo bar baz
foo bar baz
$ echo !$
echo baz
foo

```

**!***
直前に実行したコマンドの全ての引数を取得する

```sh:sample
$ echo foo bar baz
foo bar baz
$ echo !*
echo foo bar baz
foo bar baz

```

**!:n***
直前に実行したコマンドの n 番目から最後までの引数を取得する

```sh:sample
$ echo foo bar baz
foo bar baz
$ echo !:2*
echo bar baz
bar baz

```

**!:n-m**
直前に実行したコマンドの n 番目から m 番目までの引数を取得する

```sh:sample
$ echo foo bar baz FOO BAR BAZ
foo bar baz FOO BAR BAZ
$ echo !:3-5
echo baz FOO BAR
baz FOO BAR

```

**!:-n**
直前に実行したコマンドの最初から n 番目までの引数を取得する

```sh:sample
$ echo foo bar baz FOO BAR BAZ
foo bar baz FOO BAR BAZ
$ echo !:-4
echo foo bar baz FOO
foo bar baz FOO

```

**n-**
直前に実行したコマンドの n 番目から 最後の 1 個前までの引数を取得する

```sh:sample
$ echo foo bar baz
foo bar baz
$ echo !:1-
echo foo bar
foo bar

```

### 修飾指示子

**:p**
コマンドを表示のみして実行しない

```sh:sample
$ echo foo bar baz
foo bar baz
$ touch foo bar baz
$ !e:p
echo foo bar baz

```

**:h**
パスのファイル名部分を取り除きディレクトリ名を取得する

```sh:sample
$ echo /foo/bar/baz
/foo/bar/baz
$ echo !$:h
echo /foo/bar
/foo/bar

```

**:t**
パスのディレクトリ名部分を取り除きファイル名を取得する

```sh:sample
$ echo /foo/bar/baz
/foo/bar/baz
$ echo !$:t
echo baz
baz

```

**:r**
ファイル名の拡張子を取り除き "." の前を取得する

```sh:sample
$ echo foo.c
foo.c
$ echo !$:r
echo foo
foo

```

**:e**
ファイル名の拡張子を "." 付きで取得する

```sh:sample
$ echo foo.c
foo.c
$ echo !$:e
echo .c
.c


```