Vimを使ったテキスト一括操作まとめ 検索置換・ビジュアルブロックモードの応用

## この記事について

Vimを使ったテキストの一括操作の方法をまとめておきます。

Vimの一番の強み・利点は、「**あらゆる操作がコマンド・キーボードで完結するため、テキストの一括編集が圧倒的に早い**」点だと思います。

テキストの一括操作は、日常のプログラミング・コーディング作業でも頻出です。ここでは、

- ビジュアルブロックモード
- 検索置換

などの機能を活用することになります。

## 関連のあるモード・コマンド
テキストの一括編集において特に重要になるのは、この2つの機能です。

| 機能 | コマンド | できること |
| ---- | ---- | ---- |
| **ビジュアルブロックモードへの切り替え** | `<Ctrl-v>` | 複数行に対して、同じテキスト操作を一括で可能にする |
| **検索置換（現在の行）** | `:s/置き換え前/置き換え後/g` | 現在の行にある対象文字列をすべて置換する |

Vimの豊富な機能・コマンドの中でも、この2つは特に便利で、いろいろなことに応用できます。そのため、慣れるまで反復練習をする価値も大きいです。

## 具体的な利用場面
### マークダウンのリストをHTMLのリストに変換する
```markdown:書き換え前：マークダウン記法のリスト
- りんご
- みかん
- ぶどう
```
上記のテキストなら、

1. ビジュアルブロックモード(`Ctrl`+`v`)で、先頭の「-」を選択
2. `x`などで一括削除
3. ビジュアルブロックモード(`Ctrl`+`v`)で各行の先頭を選択
4. 挿入モード(`Shift`+`i`)で`<li>`と入力し、`ESC`
4. 5. ビジュアルブロックモード(`Ctrl`+`v`)で各行の末尾を選択
6. 挿入モード(`Shift`+`i`)で `</li>`と入力し、`ESC`
7. `gg`で先頭に移動し、挿入モード(`i`)で `<ul>`と入力
8. `G`で末尾に移動し、挿入モード(`i`)で `</ul>`と入力

```html:書き換え後：HTMLリスト
<ul>
    <li>りんご</li>
    <li>みかん</li>
    <li>ぶどう</li>
</ul>
```
**ビジュアルブロックモードと挿入モードを行き来する**イメージですね。
テキストの先頭（`gg`）や末尾（`G`）へのジャンプも、しっかり活用しています。

### カンマ区切り文字列すべてに、引用符（”）をつける

```text:書き換え前：引用符（”）のないカンマ区切りテキスト
aaa,bbb,ccc
```
1. ビジュアルブロックモード(`Ctrl`+`v`)で、文字列全体を選択し、`ESC`で、コマンドモードに戻る
2. `:s/,/","/g ` と入力し、カンマ(`,`)の前後に引用符（`"`）をつける
3. `gg`で先頭に移動し、挿入モード(`i`)で `"`を付け足し、`ESC`で、コマンドモードに戻る
4.  `G`で末尾に移動し、挿入モード(`i`)で `"`を付け足し、`ESC`で、コマンドモードに戻る

```text:書き換え後：引用符（”）を付けたカンマ区切りテキスト
"aaa","bbb","ccc"
```

CSVファイルのヘッダーを作成するときや、JSON形式で項目名を作るときに、よく出てきます。

### 引用符つきの単語リストから、引用符を外す
今度は逆に、引用符（”）を外す操作です。

```text:書き換え前：引用符（”）を付けたカンマ区切りテキスト
"aaa","bbb","ccc"
```
考え方は何も変わらず、
- ビジュアルブロックモードで全範囲選択
- 文字置換(`:s/,/"//g ` )

で、いけます。
**引用符（”）を削除する**という作業のみで足りる分、引用符（”）を新たに付け足すよりも簡単です。


```text:書き換え後：引用符（”）のないカンマ区切りテキスト
aaa,bbb,ccc
```

CSVのヘッダー名をそのままプログラムの変数名として使いたい場面では、こうした作業も出てきます。

### 各行のインデントをとる
```text:書き換え前：インデントあり
    aaa
    bbb
    ccc
```
1. ビジュアルブロックモード(`Ctrl`+`v`)で、不要なインデントにあたる箇所を指定
2. `d` でインデント削除

```text:書き換え後：インデントなし
aaa
bbb
ccc
```
本質は、**各行の先頭を範囲指定し、削除する**ということです。
したがって、先頭にあるカンマ(`,`)をまとめて除去する場合も、同じ要領でできます。
```text:書き換え前：カンマあり
aaa
,bbb
,ccc
```

```text:書き換え後：カンマなし
aaa
bbb
ccc
```

### 各行にカンマ(`,`)を追加する

```text:書き換え前：カンマなし
aaa
bbb
ccc
```

1. ビジュアルブロックモード(`Ctrl`+`v`)で、各行の先頭を指定
2. `Shift` + `i` で挿入モードに切り替え、カンマ(`,`)を入力し、`ESC`

```text:書き換え後：カンマあり
aaa
,bbb
,ccc
```

これも、**各行の先頭を範囲指定し、任意の文字を追加する**ことが本質です。
したがって、変数名にデータ型指定を追加する場合も、同じです。

```text:書き換え前:テキストの羅列
var1
var2
var3
```

```java:書き換え後:各変数名に、型を加えて、変数宣言にする。
int var1
int var2
int var3
```

挿入モードの切り替え時に、`Shift` + `i`とする点を忘れやすいです。（たんに`i`とするだけではダメ。）
**`Ctrl` + `v`　→`Shift` + `i`** という流れで覚えましょう。

### tsvファイルをcsvファイルに変更する

```text:書き換え前:tab区切りのtsv
banana  apple  orange
```
- tsv：tab(`    `)区切り
- csvファイル:カンマ(`,`)区切り

ここまで見てきた人なら、もう楽勝だと思います。

はい、tabをカンマに変えるだけ、つまり**文字置換**でいけますね。

1. ビジュアルブロックモード(`Ctrl`+`v`)で、対象範囲を選ぶ
    →`ggVG`とかでテキストを全範囲選択すればOK
2. 文字置換(`:s/<tab>/,/g`)

```text:書き換え後:カンマ区切りのcsv
banana,apple,orange
```

## 検索方法・ビジュアルモードの詳細
以下は補足です。
### 様々なビジュアルモード

本記事で紹介したのは、ビジュアルブロックモードのみですが、実はビジュアルモードにもいくつか種類があります。


| モード名 | コマンド | できること | 主な用途 |
| ---- | ---- | ---- | ---- |
| **ビジュアルモード (Visual Mode)** | `v` | 文字単位で選択 | *1単語だけ色を変える、特定の部分だけ削除するなど* |
| **ビジュアルラインモード (Visual Line Mode)** | `<Shift>` + `v` | *行単位で選択 | 複数行のコメントアウト、一括削除など* |
| **ビジュアルブロックモード (Visual Block Mode)** | `<Ctrl>` + `v` | 矩形（ブロック）単位で選択 | *⭐︎もっとも重要。変数名の先頭に型情報を追加、JSONのキーへの引用符を追加など。* |

もっとも重要なのは、ビジュアルブロックモードだと思います。
なぜなら、
- 一文字ずつの操作（ビジュアルモード）
　→ 挿入モード(`:i`)での一文字ずつの操作で足りるため
- 一行ずつの操作(ビジュアルラインモード )
　→ 行単位での一括操作（削除なら`dd`、コピーなら`yy`など）で足りるため

といった理由から、**あえてビジュアルモードに頼る必要性がない**ためです。

一方でビジュアルブロックモードは、複数行に一括で同じ文字列操作を適用するなど、他の機能で代替しづらい役割があります。

そのため、**複数あるビジュアルモードの使い分けがややこしい、と悩むくらいなら、まずはビジュアルブロックモードの活用に慣れる**のがおすすめです。

### 様々な検索置換の手法
また、検索置換の方法も様々です。

| コマンド | 説明 | 備考 |
| ---- | ---- | ---- |
| `:s/error/fix/g` | **現在の行**の "error" をすべて "fix" に置換 | *⭐︎最重要* ||
| `:%s/error/fix/g` | **ファイル全体**の "error" をすべて "fix" に置換 ||
| `:%s/error/fix/gc` | 置換ごとに**確認しながら**実行 ||
| `:%s/error/fix/gi` | 大文字小文字を**区別せずに**置換 || 

本記事では一番上`:s/error/fix/g`しか紹介していませんが、このように検索方法も実は色々です。
※本当は、ここに掲載しきれないほど沢山あります。

流石に全部は覚えきれないので、**どんなことができるかだけざっくり把握して、必要になったら都度調べるのがおすすめ**です。

### 作業時の注意点：検索時には、`'<,'>`という表記があるのを確認
これは**ビジュアルブロックモードの選択範囲が、検索対象になっている**という意味です。
これが出ていれば、`s/error/correct/g`の構文に沿って、文字置換ができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3664630/12cbec0e-7da4-4fad-812d-e047872ee188.png)

筆者のマシンで`:`したときが上記の表示。左下に注目。

## まとめ
本記事では、テキストの一括操作を取り上げました。この辺りの作業は、慣れていないとついマウスとキーボードを何往復もしがちです。そして時間をかけた作業ほど、ミスもしがちなんですよね。

一方Vimを使うとキーボードだけで完結するため、**慣れればとにかく早いです**。

**テキストの取り扱いがシステマチックに行える**というVimの強みが伝われば嬉しいです。普段は自分の好きなエディタ(VSCodeなど)を使うとしても、こうした一括テキスト操作をする際、Vimの活用も検討してみてください。

## 筆者からひと言
他にも便利なVimの置換技や活用法を知っている人は、ぜひコメントで共有してください。

## 関連記事
本記事は、

https://qiita.com/Inclusive_Solutions_LLC/items/67d030056411b839ce55

の続編です。**Vimのコマンド操作に全般慣れていない**という人は、まずはこちらを参照してください。

また、**Vimって何？触ったことすらないんだけど?** な人は、

https://qiita.com/Inclusive_Solutions_LLC/items/2c4b18f1a1f77efa7449

こちらを参照してください。