Vimで改行を含む置換を行う方法を詳しく解説!

プログラミング・IT

テキスト処理において「複数行にまたがる置換」や「改行の挿入・削除」を行いたい場面は少なくありません。例えば:

  • 「2行になっているテキストを1行にまとめたい」
  • 「カンマの後に改行を入れて見やすくしたい」
  • 「改行コードを削除してスペースに変えたい」
  • 「複数行のパターンを一度に置換したい」

特にVimを使っていると、「改行を対象にどうやって置換すればいいの?」と疑問に思うことがあるでしょう。

一般的な文字列置換とは異なり、改行コードの扱いには特別な知識が必要です。

この記事では、Vimで改行を含む置換を行う具体的な方法とその注意点を、初心者にもわかりやすく詳しく解説します。

スポンサーリンク
  1. 改行を扱うための基本知識
    1. Vimにおける改行コードの種類
    2. Vimの置換における改行の表現方法
    3. 基本的な置換コマンドの復習
  2. 改行を含む検索パターン:複数行のマッチング
    1. 基本的な複数行検索
    2. より複雑な複数行パターン
    3. 柔軟な複数行パターン
    4. HTMLやXMLでの複数行タグ処理
  3. 置換結果に改行を挿入するテクニック
    1. 基本的な改行挿入
    2. 特定のパターンで改行を挿入
    3. プログラムコードの整形
    4. CSVファイルの整形
  4. 改行の削除と行の結合
    1. 基本的な改行削除
    2. 改行をスペースに置換
    3. 条件付きの改行削除
    4. プログラムコードの1行化
  5. 高度な改行処理テクニック
    1. 空行の処理
    2. 行の先頭・末尾での改行処理
    3. 特定の条件での改行挿入
  6. Vimの標準機能との併用
    1. Jキーによる行結合
    2. gJキーによるスペースなし結合
    3. マクロとの組み合わせ
  7. 実践的な使用例
    1. データファイルの処理
    2. プログラムコードの整形
    3. ドキュメントの整形
  8. よくある問題と解決方法
    1. 問題1:改行を含む検索が動作しない
    2. 問題2:置換後の改行が正しく挿入されない
    3. 問題3:複数行パターンの一部だけがマッチする
    4. 問題4:大きなファイルでの処理が遅い
  9. 設定とカスタマイズ
    1. .vimrcでの便利な設定
    2. 便利なキーマッピング
    3. カスタムコマンドの作成
  10. トラブルシューティング
    1. デバッグ方法
    2. バックアップの重要性
    3. アンドゥ機能の活用
  11. まとめ:改行置換マスターへの道
    1. 基本的な使い分け
    2. よく使う基本パターン

改行を扱うための基本知識

Vimにおける改行コードの種類

まず、改行コードについて理解しましょう。

コンピューターでは、改行を表現するために以下の特殊文字が使われます:

主要な改行コード

  • LF(Line Feed):Unix/Linux系で使用(\n
  • CR(Carriage Return):古いMac系で使用(\r
  • CRLF:Windows系で使用(\r\n

Vimでは主にLF(\n)が使われますが、置換操作では異なる表現方法を使い分ける必要があります。

Vimの置換における改行の表現方法

Vimで改行を扱う際は、検索と置換で異なる文字を使用します:

検索パターンでの改行

\n    " 改行文字を検索する際に使用

置換後の文字列での改行

\r    " 置換後に改行を挿入する際に使用

この違いの理由

  • \n:「New Line」の略で、既存の改行を検索する
  • \r:「Return」の略で、新しく改行を作成する

基本的な置換コマンドの復習

改行の置換を学ぶ前に、Vimの基本的な置換コマンドを復習しましょう:

:s/検索パターン/置換文字列/    " 現在行のみ
:%s/検索パターン/置換文字列/g  " ファイル全体、すべて置換

コマンドの構成要素

  • ::コマンドモードの開始
  • %:ファイル全体を対象
  • s:substitute(置換)コマンド
  • g:global(行内のすべてを対象)

改行を含む検索パターン:複数行のマッチング

基本的な複数行検索

複数行にまたがるテキストを検索するには、\nを使って改行を表現します。

例1:2行のパターンを検索

:%s/Hello\nWorld/Hello World/g

実行前

Hello
World
Good morning
Hello
World

実行後

Hello World
Good morning
Hello World

より複雑な複数行パターン

例2:空行を含むパターンの検索

:%s/line1\n\nline3/line1, line3/g

実行前

line1

line3

実行後

line1, line3

柔軟な複数行パターン

例3:任意の文字を含む2行パターン

:%s/\(.*\)\n\(.*\)/\1 - \2/g

実行前

First line
Second line
Another line
One more line

実行後

First line - Second line
Another line - One more line

パターンの説明

  • \(.*\):任意の文字列をキャプチャ(記憶)
  • \1\2:キャプチャした文字列を参照

HTMLやXMLでの複数行タグ処理

例4:複数行にわたるHTMLタグを1行に

:%s/<div>\n\s*\(.*\)\n<\/div>/<div>\1<\/div>/g

実行前

<div>
  Hello World
</div>
<div>
  Another content
</div>

実行後

<div>Hello World</div>
<div>Another content</div>

置換結果に改行を挿入するテクニック

基本的な改行挿入

置換後に改行を挿入したい場合は、\rを使用します。

例1:カンマの後に改行を挿入

:%s/,/,\r/g

実行前

apple,banana,cherry,date

実行後

apple,
banana,
cherry,
date

特定のパターンで改行を挿入

例2:ピリオドの後に改行を挿入

:%s/\./.\r/g

実行前

This is sentence one.This is sentence two.This is sentence three.

実行後

This is sentence one.
This is sentence two.
This is sentence three.

プログラムコードの整形

例3:セミコロンの後に改行(JavaScript等)

:%s/;/;\r/g

実行前

let a = 1;let b = 2;let c = 3;

実行後

let a = 1;
let b = 2;
let c = 3;

CSVファイルの整形

例4:CSVを縦並びに変換

:%s/,/\r/g

実行前

Name,Age,City,Country

実行後

Name
Age
City
Country

改行の削除と行の結合

基本的な改行削除

改行を削除して複数行を1行にまとめるテクニックです。

例1:すべての改行を削除

:%s/\n//g

実行前

This is
a multi-line
text example

実行後

This isa multi-linetext example

改行をスペースに置換

例2:改行をスペースに変換

:%s/\n/ /g

実行前

This is
a multi-line
text example

実行後

This is a multi-line text example

条件付きの改行削除

例3:空行ではない改行のみ削除

:%s/\([^\n]\)\n\([^\n]\)/\1 \2/g

このコマンドは、空行は保持しながら通常の改行のみを削除します。

プログラムコードの1行化

例4:複数行の配列定義を1行に

:%s/,\n\s*/, /g

実行前

let array = [
  'item1',
  'item2',
  'item3'
];

実行後

let array = [
  'item1', 'item2', 'item3'
];

高度な改行処理テクニック

空行の処理

空行をすべて削除

:%s/\n\n/\n/g

または、より確実に:

:g/^$/d

複数の空行を1つの空行にまとめる

:%s/\n\{2,}/\r\r/g

行の先頭・末尾での改行処理

行末の特定文字の後に改行を追加

:%s/\(;\|}\)$/\1\r/g

実行前

function test() { console.log('hello'); }

実行後

function test() { console.log('hello');
}

特定の条件での改行挿入

数字の後に改行を挿入

:%s/[0-9]/&\r/g

実行前

abc123def456ghi

実行後

abc1
2
3
def4
5
6
ghi

Vimの標準機能との併用

Jキーによる行結合

置換コマンド以外の方法として、Jキーによる行結合があります:

ビジュアルモードでの結合

  1. Vキーでビジュアルラインモードに入る
  2. 矢印キーで複数行を選択
  3. Jキーで選択行を結合

ノーマルモードでの結合

5J    " 現在行から5行を結合

gJキーによるスペースなし結合

通常のJキーはスペースを挿入しますが、gJキーはスペースを挿入せずに結合します:

gJ    " スペースなしで次の行と結合

マクロとの組み合わせ

複雑な改行処理をマクロで自動化

qa                            " マクロ記録開始(aレジスタ)
:%s/,/,\r/g                   " カンマの後に改行
Enter
q                             " マクロ記録終了

@a                            " マクロを実行

実践的な使用例

データファイルの処理

例1:ログファイルの改行統一

" タイムスタンプの後に改行を挿入
:%s/\([0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\} [0-9]\{2\}:[0-9]\{2\}:[0-9]\{2\}\)/\r\1/g

例2:CSVファイルをJSON風に整形

:%s/\([^,]*\),\([^,]*\)/{\r  "key": "\1",\r  "value": "\2"\r},/g

プログラムコードの整形

例3:インライン関数を複数行に展開

:%s/{\([^}]*\)}/{\r  \1\r}/g

実行前

function test() {console.log('hello');}

実行後

function test() {
  console.log('hello');
}

例4:配列要素を1行ずつに分割

:%s/\[\([^\]]*\)\]/[\r\1\r]/g
:%s/,/,\r/g

ドキュメントの整形

例5:マークダウンリストの整形

:%s/\*\s*/\r* /g

実行前

* item1 * item2 * item3

実行後

* item1 
* item2 
* item3

よくある問題と解決方法

問題1:改行を含む検索が動作しない

症状

:%s/line1\nline2/replacement/g

が期待通りに動作しない

解決方法

" より明示的なパターンを使用
:%s/line1\_.\{-}line2/replacement/g

解説

  • \_.:改行を含む任意の文字
  • \{-}:非貪欲マッチング(最短マッチ)

問題2:置換後の改行が正しく挿入されない

症状 \nを使って改行を挿入しようとしても、リテラル文字「\n」が挿入される

解決方法

" 正しい書き方
:%s/pattern/replacement\r/g

" 間違い
:%s/pattern/replacement\n/g

問題3:複数行パターンの一部だけがマッチする

症状 複数行にまたがるパターンの一部だけが置換される

解決方法

" 'very magic'モードを使用
:%s/\v(line1)\n(line2)/\1 \2/g

解説

  • \v:very magicモードで正規表現を簡単に
  • ():キャプチャグループ(\(\)のエスケープ不要)

問題4:大きなファイルでの処理が遅い

症状 大きなファイルで改行を含む置換が非常に遅い

解決方法

" 描画を無効にして高速化
:set lazyredraw
:%s/pattern/replacement/g
:set nolazyredraw
:redraw

設定とカスタマイズ

.vimrcでの便利な設定

" 改行を含む検索を有効化
set magic

" 検索結果のハイライト
set hlsearch

" インクリメンタル検索
set incsearch

" 改行コードの表示
set list
set listchars=eol:↲,tab:»\ ,space:·

便利なキーマッピング

" よく使う改行処理をマッピング
nnoremap <Leader>j :%s/,/,\r/g<CR>        " カンマで改行
nnoremap <Leader>J :%s/\n/ /g<CR>         " 改行をスペースに
nnoremap <Leader>n :g/^$/d<CR>            " 空行削除

カスタムコマンドの作成

" カスタムコマンドを定義
command! JoinLines %s/\n/ /g
command! SplitCommas %s/,/,\r/g
command! RemoveEmptyLines g/^$/d

" 使用例
:JoinLines        " すべての行を結合
:SplitCommas      " カンマで分割
:RemoveEmptyLines " 空行を削除

トラブルシューティング

デバッグ方法

置換前のテスト

" パターンがマッチするか確認
/pattern

" マッチ数を確認
:%s/pattern//gn

段階的な置換

" まず小さな範囲でテスト
:1,10s/pattern/replacement/g

" 成功したら全体に適用
:%s/pattern/replacement/g

バックアップの重要性

" 大規模な置換前にバックアップ
:w backup_%
:%s/complex_pattern/replacement/g
" 問題があれば :e backup_% で復元

アンドゥ機能の活用

u          " 1回戻る
Ctrl-R     " やり直し
:earlier 1m " 1分前の状態に戻る
:later 1m   " 1分後の状態に進む

まとめ:改行置換マスターへの道

Vimでの改行を含む置換について、基本から応用まで詳しく解説してきました。重要なポイントをまとめます:

基本的な使い分け

検索での改行

\n    " 既存の改行を検索

置換での改行

\r    " 新しく改行を挿入

よく使う基本パターン

複数行を1行に結合

:%s/\n/ /g              " 改行をスペースに
:%s/\n//g               " 改行を削除

1行を複数行に分割

:%s/,/,\r/g             " カンマの後に改行
:%s/\./.\r/g            " ピリオドの後に改行

複数行パターンの置換

:%s/line1\nline2/replacement/g

コメント

タイトルとURLをコピーしました