テキスト処理において「複数行にまたがる置換」や「改行の挿入・削除」を行いたい場面は少なくありません。例えば:
- 「2行になっているテキストを1行にまとめたい」
- 「カンマの後に改行を入れて見やすくしたい」
- 「改行コードを削除してスペースに変えたい」
- 「複数行のパターンを一度に置換したい」
特にVimを使っていると、「改行を対象にどうやって置換すればいいの?」と疑問に思うことがあるでしょう。
一般的な文字列置換とは異なり、改行コードの扱いには特別な知識が必要です。
この記事では、Vimで改行を含む置換を行う具体的な方法とその注意点を、初心者にもわかりやすく詳しく解説します。
改行を扱うための基本知識

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キーによる行結合があります:
ビジュアルモードでの結合
- Vキーでビジュアルラインモードに入る
- 矢印キーで複数行を選択
- 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
コメント