【bat】バッチファイルで改行する方法完全ガイド|echo.・行継続・変数内改行・ファイル書き込み・CRLF/LF変換まで徹底解説

バッチファイルで「改行」が必要な場面は大きく2つあります。ひとつは画面出力での空行・段落分け、もうひとつはファイルに書き込む改行コード(CRLF/LF)の制御です。さらに「変数の中に改行を含める」という高度な技法も存在します。この記事ではそれぞれのケースを体系的に解説します。

この記事でわかること

  • echo.echo:echo/ の違いと使い分け
  • ^(行継続文字)でコマンドを複数行に分割する方法
  • 変数の中に改行コードを埋め込む裏技(遅延展開との組み合わせ)
  • テキストファイルへ改行を書き込む方法
  • CRLF(Windows)と LF(Unix)の違いと PowerShell での変換
  • 改行コードが原因で起きるトラブルと対処法
  • 実践例3本(整形表示・ヘルプメッセージ・ファイル生成)
スポンサーリンク

1. echo. / echo: / echo/ で空行を出力する

画面に空行(改行のみの行)を出力する最も基本的な方法は echo. です。ただし echo. 以外にも同じ目的で使われる書き方があり、それぞれ微妙な違いがあります。

書き方 動作 推奨度・注意点
echo. 空行を出力(最も一般的) ★★★ ただし echo. という名前のファイルがあると誤動作する
echo: 空行を出力 ★★★ ファイル名の誤動作なし・高速・推奨
echo/ 空行を出力 ★★☆ 動作するが一部環境で挙動が異なる場合あり
echo( 空行を出力 ★★☆ 動作するがコードの可読性が低い
echo (末尾スペース) スペース1文字を出力(空行ではない) ★☆☆ 非推奨
@echo off

echo === 処理開始 ===
echo.
echo ステップ1: ファイルをコピーしています...
echo.
echo ステップ2: データを検証しています...
echo.
echo === 処理完了 ===
echo: が最も安全な空行出力
echo. はカレントディレクトリに echo. という名前のファイルが存在すると、そのファイルを開こうとしてエラーになるという既知の問題があります。実務では echo: を使うのが最も安全です。echo. と同じ空行を出力しますが、ファイル名との衝突問題がありません。

1-1. echo. を使った出力の整形例

@echo off

:: ヘッダーとフッターで区切り線を入れる
echo ========================================
echo  バックアップ処理
echo  %DATE% %TIME%
echo ========================================
echo:
echo 処理対象: C:\data\
echo 保存先  : D:\backup\
echo:
echo 処理を開始します...

2. ^ 行継続文字:コマンドを複数行に分割する

長いコマンドは ^(キャレット)を行末に置くことで、次の行に継続して書けます。コマンドプロンプトはこれを1行として解釈します。

@echo off

:: robocopy コマンドを複数行に分割して可読性を上げる
robocopy ^^
    C:\source ^^
    D:\destination ^^
    /mir ^^
    /r:3 ^^
    /w:10 ^^
    /log:D:\logs\backup.log

:: xcopy も同様
xcopy "C:\My Documents\*.docx" ^^
     "D:\backup\documents\" ^^
     /y /i
^ の後には何も書いてはいけない(スペースも NG)
^ の直後には改行のみが来る必要があります。^ (キャレット + スペース)にしてしまうと行継続にならず、^ がエスケープ文字として次の文字(スペース)をエスケープしてしまいます。テキストエディタの「行末スペースの自動除去」機能がある場合は安心ですが、目視で確認するのが確実です。

2-1. ^ でコマンドを継続するときの注意(コメントの扱い)

@echo off

:: OK: コメントは継続行の前に置く
:: ログ付きコピー
xcopy C:\src D:\dst /y /i ^^
     /exclude:C:\exclude.txt

:: NG: 継続行の途中に :: コメントを挟むとエラーになる
:: xcopy C:\src D:\dst /y /i ^   ← ここに :: を書くと壊れる
::      /exclude:C:\exclude.txt

2-2. IF・FOR 内でのコマンド複数行展開

@echo off

:: if 文内のコマンドブロックは括弧で囲めば自然に複数行にできる
if exist "C:\data\input.csv" (
    echo ファイルが見つかりました
    copy "C:\data\input.csv" "D:\backup\"
    echo コピー完了
) else (
    echo ファイルが見つかりません
    exit /b 1
)

:: for ループも同様に括弧内で複数行に書ける
for %%F in (*.log) do (
    echo 処理中: %%F
    copy "%%F" "D:\archive\"
)
if・for の括弧内は ^ なしで複数行に書ける
閉じ括弧 ) が来るまでは自動的に継続行として扱われるため、if ( ... )for (...) do ( ... ) の中は^ なしで自然に複数行に分けられます。可読性が高いのでこちらを積極的に活用してください。

3. 変数の中に改行コードを埋め込む

バッチファイルには「変数に改行を格納する」という少し高度な技法があります。複数行のメッセージを1つの変数にまとめて扱いたいときに便利です。

3-1. ^ と遅延展開を使う方法(クラシックな手法)

@echo off
setlocal enabledelayedexpansion

:: 改行コードを変数に格納する
:: 重要: set ^NL=^ の後に「空行を2行」入れることで改行文字が格納される
(set ^NL=^

)

:: 使い方:!NL! で改行を挿入
set MSG=1行目!NL!2行目!NL!3行目
echo !MSG!
この方法は環境・cmd.exe バージョンによって動作が不安定
変数に改行を埋め込む方法はトリッキーで、環境によって動作が変わります。複数行メッセージの表示には、素直に echo を複数回呼ぶか、type でテキストファイルを表示する方法の方が確実です。

3-2. より確実な方法:echo を複数回呼ぶ

@echo off

:: シンプルで確実:echo を複数行に分けて書く
:show_help
echo 使い方:
echo:
echo   backup.bat [オプション]
echo:
echo オプション:
echo   --src    コピー元フォルダ
echo   --dst    コピー先フォルダ
echo   --log    ログファイルのパス
echo:
echo 例:
echo   backup.bat --src C:\data --dst D:\backup --log C:\logs\bk.log
goto :eof

3-3. テキストファイルを事前に用意して type で表示する

@echo off

:: 複雑な複数行メッセージはファイルに分離する
if "%1"=="/?" (
    type "%~dp0help.txt"
    exit /b 0
)

:: help.txt の内容:
::   使い方:
::
::   backup.bat [オプション]
::   ...

4. ファイルへ改行を書き込む

4-1. echo. でファイルに空行を追記する

@echo off

:: テキストファイルを生成(空行あり)
echo 1行目 > output.txt
echo: >> output.txt
echo 3行目 >> output.txt
echo: >> output.txt
echo 5行目 >> output.txt

echo 書き込み完了
type output.txt

4-2. 複数行テキストをまとめて書き込む(ヒアドキュメント風)

@echo off

:: 括弧 + リダイレクトでまとめて書き込む(ヒアドキュメント風)
(
    echo [設定ファイル]
    echo:
    echo TARGET_DIR=C:\data
    echo BACKUP_DIR=D:\backup
    echo RETAIN_DAYS=30
    echo:
    echo # 上記を変更する場合は管理者に連絡してください
) > config.txt

echo config.txt を生成しました
type config.txt
括弧 + リダイレクトは最も可読性の高いファイル生成方法
( echo ...; echo ... ) > ファイル の形式は、各行を個別にリダイレクトするよりもすっきりして読みやすく、パフォーマンスも向上します(ファイルを1回だけ開いて書き込む)。設定ファイル・ログヘッダーの生成に最適です。

4-3. ファイルに書き込まれる改行コードについて

バッチの echo + リダイレクトで書き込まれる改行コードはCRLF(\r\n、Windows 形式)です。Unix/Linux ツールで読み込む場合は LF に変換が必要なことがあります。

改行コード 表記 環境 バッチでの挙動
CRLF \r\n / 0x0D 0x0A Windows echo で書き込まれる(デフォルト)
LF \n / 0x0A Unix / Linux / macOS バッチ単体では直接書けない → PowerShell が必要
CR \r / 0x0D 旧 Mac OS(現在はほぼ見ない) バッチでは通常扱わない

ファイルへの書き込みとリダイレクトの詳細は リダイレクト(> >> 2>&1)完全ガイド、テキストファイルの作成方法全般は テキストファイルを作成する方法 を参照してください。

5. CRLF と LF の変換(PowerShell 活用)

5-1. CRLF → LF に変換する(Linux 向けファイル生成)

@echo off

:: PowerShell で CRLF → LF に変換(BOMなし UTF-8 で保存)
powershell -Command ^^
    "$text = Get-Content -Path 'input.txt' -Raw;" ^^
    "$text = $text -replace '`r`n', '`n';" ^^
    "[System.IO.File]::WriteAllText('output_lf.txt', $text, [System.Text.UTF8Encoding]::new($false))"

echo LF 変換完了: output_lf.txt

5-2. LF → CRLF に変換する(Windows 向けに変換)

@echo off

:: PowerShell で LF → CRLF に変換
powershell -Command ^^
    "$text = [System.IO.File]::ReadAllText('input_lf.txt');" ^^
    "$text = $text -replace '(?<!`r)`n', '`r`n';" ^^
    "[System.IO.File]::WriteAllText('output_crlf.txt', $text)"

echo CRLF 変換完了: output_crlf.txt

5-3. PowerShell で LF のみのファイルを直接生成する

@echo off

:: LF のみで改行するファイルを PowerShell で生成
powershell -Command ^^
    "$lines = @('1行目', '', '3行目', '', '5行目');" ^^
    "$content = $lines -join "`n";" ^^
    "[System.IO.File]::WriteAllText('lf_only.txt', $content, [System.Text.UTF8Encoding]::new($false))"

echo LF ファイル生成完了: lf_only.txt

文字コードと改行コードの問題(UTF-8・Shift-JIS・BOM)については 文字化けを直す方法完全ガイド も参照してください。

6. 改行が原因で起きるトラブルと対処法

症状 原因 対処法
echo. がファイルを開こうとするエラーが出る カレントに echo. という名前のファイルが存在する echo: に変更する
ファイル末尾に余分な空白行が入る echo. の後ろにスペースが入っている echo: を使う、またはスペースを除去する
for /f がファイルの空行を読み飛ばす for /f は仕様として空行をスキップする type で別の方法で処理するか PowerShell を使う
変数の末尾に改行が入って比較が失敗する set /pfor /f で取得した値に見えない CRLF が付く set "VAR=%VAR:"=%" でクォートを除去するか PowerShell で処理
Linux サーバーに送ったファイルで改行コードが二重になる CRLF のファイルを LF 環境で処理すると \r が残る 送信前に CRLF → LF 変換してから転送する
echo で % が消える / 変数が展開されてしまう echo%VAR% を自動展開する echo %%VAR%%(バッチ内)または echo %VAR% の前に set VAR で確認

6-1. for /f の空行スキップ問題の回避

@echo off

:: for /f は空行をスキップするため行番号がずれる
:: 回避策1: eol に存在しない文字を指定して空行を保持
for /f "usebackq eol=| delims=" %%L in ("data.txt") do (
    echo %%L
)

:: 回避策2: PowerShell で読み込む(空行も処理)
powershell -Command "Get-Content 'data.txt' | ForEach-Object { Write-Host $_ }"

変数展開のトラブル全般は 変数展開が思った通りに動かない原因と修正方法 も参照してください。

7. 実践例3本

実践例1:整形された処理結果レポートを表示する

@echo off
setlocal

:: 処理結果を整形して表示する
set SRC=C:\data
set DST=D:\backup
set FILE_COUNT=0
set ERR_COUNT=0

for %%F in ("%SRC%\*.csv") do (
    set /a FILE_COUNT+=1
    copy "%%F" "%DST%\" >nul 2>&1
    if errorlevel 1 set /a ERR_COUNT+=1
)

:: 区切り線で整形(echo: で空行を挿入)
echo:
echo ======================================
echo   処理完了レポート
echo   %DATE%  %TIME%
echo ======================================
echo:
echo   コピー元 : %SRC%
echo   コピー先 : %DST%
echo:
echo   処理ファイル数 : %FILE_COUNT%
echo   エラー数       : %ERR_COUNT%
echo:
if %ERR_COUNT% gtr 0 (
    echo   [警告] %ERR_COUNT% 件のコピーに失敗しました。
) else (
    echo   [OK] すべてのファイルを正常にコピーしました。
)
echo ======================================
echo:

実践例2:バッチファイルに /? オプションでヘルプを表示する

@echo off

:: /? または --help でヘルプを表示
if /i "%~1"=="/?" goto :show_help
if /i "%~1"=="--help" goto :show_help

:: 通常処理
echo 処理を実行します...
goto :eof

:show_help
echo:
echo 【使い方】  deploy.bat [オプション]
echo:
echo 【オプション】
echo   /src  ^<パス^>    コピー元フォルダを指定
echo   /dst  ^<パス^>    コピー先フォルダを指定
echo   /log  ^<パス^>    ログファイルのパスを指定
echo   /dry          ドライランモード(コピーしない)
echo   /?            このヘルプを表示
echo:
echo 【例】
echo   deploy.bat /src C:\build /dst \\server\deploy /log C:\logs\dp.log
echo:
exit /b 0
echo 内の < > は ^^ でエスケープする
echo ^<パス^> のように、<>^<^> にエスケープしないとリダイレクト文字として解釈されます。|(パイプ)も同様に ^| にしてください。

実践例3:複数行の設定ファイルをバッチから生成する

@echo off
setlocal

:: 引数から設定値を受け取る
set SERVER=%~1
set PORT=%~2
set DB_NAME=%~3

:: デフォルト値
if "%SERVER%"=="" set SERVER=localhost
if "%PORT%"=="" set PORT=5432
if "%DB_NAME%"=="" set DB_NAME=myapp

:: 設定ファイルを生成(括弧 + リダイレクトで一括書き込み)
(
    echo # アプリケーション設定ファイル
    echo # 生成日時: %DATE% %TIME%
    echo:
    echo [database]
    echo host     = %SERVER%
    echo port     = %PORT%
    echo dbname   = %DB_NAME%
    echo:
    echo [logging]
    echo level    = INFO
    echo file     = C:\logs\app.log
    echo:
    echo # このファイルは自動生成されました
    echo # 手動で変更した場合、次回実行時に上書きされます
) > app.config

echo 設定ファイルを生成しました: app.config
echo:
type app.config

@echo off の仕組みや echo コマンドの活用については @echo off を使いこなす完全ガイド も参照してください。

8. まとめ:改行パターン別チートシート

用途 方法 ポイント
画面に空行を出力 echo: echo. より安全(ファイル名衝突なし)
コマンドを複数行に分割 ^(行末に置く) ^ の後にスペース・コメントを書かない
if/for ブロックを複数行に 括弧 ( ... ) ^ 不要・自然に複数行
複数行テキストをファイルに一括書き込み ( echo ...; echo ... ) > file 可読性・パフォーマンス◎
ファイル末尾に空行を追記 echo: >> file ログの区切りに便利
for /f で空行を保持 eol=| を指定 | は通常のテキストに出てこない文字
CRLF → LF 変換 PowerShell -replace Linux向けファイル生成に
LF のみのファイル生成 PowerShell [IO.File]::WriteAllText バッチ単体では不可

FAQ

Qecho. と echo: どちらを使えばよいですか?

A実務では echo: を推奨します。echo. はカレントディレクトリに同名のファイルが存在するとエラーになる既知の問題があります。echo: は完全に同じ空行を出力しますが、その問題がありません。どちらも正常に動作する場合はどちらでも構いませんが、チームの規約で統一するとよいでしょう。

Q^(行継続)を使ったのにエラーになります。

Aよくある原因は ^ の後ろにスペースや他の文字が入っていることです。^ の直後は改行のみにしてください。また、rem:: コメントの行に ^ を書くとその行も継続対象になり、意図しない動作になることがあります。

Qecho コマンドで < や > を表示するにはどうすればよいですか?

A^<^> にエスケープしてください。echo A ^< BA < B と表示されます。パイプ |^|、アンパサンド &^& です。

Qバッチで生成したファイルを Linux で使うと改行コードが二重になります。

Aバッチの echo は CRLF(\r\n)で書き込みます。Linux で読み込むと \r(CR)が残って文字化けします。転送前に PowerShell で CRLF → LF 変換してください:powershell -Command "$t=Get-Content file.txt -Raw; $t=$t -replace '\`r\`n','\`n'; [IO.File]::WriteAllText('file_lf.txt',$t,[Text.UTF8Encoding]::new($false))"

Qfor /f で読み込んだ変数の末尾に謎の空白や改行が入っています。

Afor /f は行末の空白を自動的に除去しますが、ファイルの改行コードが CRLF の場合に \r が残ることがあります。set "VAR=%VAR%"(ダブルクォートで囲む)で末尾スペースを除去するか、PowerShell の Get-Content で読み込んでください。詳しくは「変数の末尾に余計な空白が入るときの対策」も参照してください。

Qヘルプテキストなど長い複数行メッセージをバッチで表示する最善の方法は?

A3つのアプローチがあります。①echo を複数行に並べる(シンプル・推奨)、②別のテキストファイルに書いておいて type help.txt で表示する(大量テキストに最適)、③PowerShell の here-string を呼び出す。長いヘルプメッセージは②のファイル分離が最も保守しやすいです。