解説
文字の中の%が変わる?Bashのprintfで書式と表示する値を分けよう
Bashのprintfへ文字をそのまま渡す基本を練習。固定の書式、値を囲む引用符、改行、エスケープの違いを、ファイルを書き換えない作例で確かめる。

画面へそのまま出したい文字に%や\nが入っていたら、printfの表示が変わった。Bashのprintfでは、「表示の指示」と「表示するデータ」を別の引数へ渡すと整理しやすいよ。
このページでできるようになるのは、変数の文字列を一行として表示すること。Bashが使えるターミナルを用意しよう。ファイルの作成や変更、外部への通信はせず、画面への出力だけで確かめる。
一つ目は書式、二つ目からが値
printfは書式に従って文字を出力するコマンド。引数は、コマンドへ渡すそれぞれの値のことだよ。
printf '%s\n' 'Progress: 100% ready'
最初の'%s\n'が書式。%sは次の引数を文字列として置く場所、\nは改行の指示になる。結果はProgress: 100% readyと一行に表示され、その後に改行が入る。
ここでデータ側の100%は書式として解釈されない。%を含んだ文字を表示するために、その値自体を書き換える必要はないんだ。
変数も、引用符で一つの値として渡す
次を一つのまとまりで実行してみよう。括弧の中だけで変数を使うため、同じ名前の変数が普段の端末にあっても値を変更したままにしないよ。
(
practice_text='Progress: 100% ready'
printf '%s\n' "$practice_text"
practice_text='line1\nline2'
printf '%s\n' "$practice_text"
)
期待する出力は次の二行。
Progress: 100% ready
line1\nline2
二行目の\nは、バックスラッシュとnの二文字のまま残る。値を一重引用符で代入したことに加え、表示側では%sを使っているためだよ。変数を展開する"$practice_text"の二重引用符は、空白などを含む値を一つの引数として保つために付けている。
値をそのまま第一引数にするprintf "$practice_text"では、値の中身が書式になる。書式の特別な文字が働いたり、エラーになったりするため、任意の文章をそのまま出す用途とは分けよう。
%bは、値の中のエスケープも読む
(
practice_text='line1\nline2'
printf '%b\n' "$practice_text"
)
この出力では、line1とline2が別々の行になる。%bは、対応する引数のバックスラッシュによるエスケープも展開するBashの指定だよ。
文字として残すのか、改行の指示として読むのかを先に決めよう。「引用符で囲んだから、中身がどこでも文字のまま」とは限らない。シェルが一つの引数にまとめた後に、printf自身がその引数をどう読むかという段階があるんだ。
複数の値と空の値も見てみよう
printf 'item=<%s>\n' 'red blue' '' '-n'
item=<red blue>
item=<>
item=<-n>
書式は必要に応じて繰り返し使われる。この例では三つの値がそれぞれ一行になる。空文字も引数として渡っているため、二行目には<>だけが残るよ。-nもデータ側なので、この例では表示する文字列として扱われる。
一方、書式自体へ%を書きたい場合は%%と二つ並べる。
printf 'rate=%s%%\n' '100'
結果はrate=100%。データにある%を読む場合と、書式の中に%を置く場合を区別しよう。
思った表示にならないときの確認順
- 第一引数が固定の書式になっているか見る。
- 値を渡す変数が二重引用符で囲まれているか見る。
- 値の\nを文字のまま残すなら%s、展開する意図があるなら%bか確認する。
- 書式の中の%を文字として出す場合は%%か見る。
この例はBash用なので、PowerShellなどへそのまま貼らず、使っているシェルを確認してね。終わったら元の端末へ戻るだけ。ファイルや永続設定を作っていないため、削除する後始末はないよ。
編集部では2026年11月1日にGNU Bash 5.2のマニュアルを確認し、Bash 5.2.37で本文の出力と空文字・空白・先頭のハイフンを照合した。シェルの一重・二重引用符、入力した一行を保つreadの-rとIFSにもつながるよ。

みんなのコメント 0
感想や、試してみたことを聞かせてね。コメント・返信は承認後に公開されます。
最初のコメントをどうぞ。