Shell printf コマンド

前の章ではShellのechoコマンドを学びました。この章ではShellのもう1つの出力コマンドであるprintfを学びます。

printf(print formatted)はフォーマット済み出力を行うためのShellコマンドで、C言語のprintf()関数に由来します。

とechoとは異なり、printf自動的に改行を追加せず、出力の形式を正確に制御できます。

printfはPOSIX標準で定義されているため、printfを使うスクリプトはechoを使うよりも移植性が高くなります。

printfは引用符で囲まれたテキストまたはスペース区切りの引数を使用します。また、printfの中でフォーマット文字列を使用でき、文字列の幅や左右揃えなども指定できます。デフォルトのprintfはechoのように自動で改行を追加しないため、手動で追加できます。\n。

なぜprintfを使うのか?

  1. 書式制御:フィールド幅、精度、配置(揃え方)を指定できます
  2. 型安全性:異なる型のデータ(整数、浮動小数点数、文字列など)には対応する書式指定子があります
  3. 移植性:動作が異なるシステムやShellでもより一貫しています
  4. 複雑な出力:テーブルやレポートなどの構造化された出力の生成に適しています

基本構文

printfコマンドの構文:

printf  format-string  [arguments...]

引数の説明:

  • format-string:通常の文字と書式指定子を含む文字列
  • arguments...:書式指定子に対応する変数または値

書式指定子は%文字で始まり、その後に1つ以上の文字が続き、出力の形式を指定します。よく使う書式指定子は次のとおりです:

  • %s:文字列
  • %d:10進整数
  • %f:浮動小数点数
  • %c:文字
  • %x:16進数
  • %o:8進数
  • %b:2進数
  • %e:科学的記数法で表される浮動小数点数

動作の流れ

  1. フォーマット文字列を解析し、通常の文字はそのまま出力します
  2. 書式指定子(%で始まる)に出会った場合:
    • 次の引数を読み取ります
    • 指定子で指定された書式に従ってその引数を処理します
    • 結果を出力に挿入します
  3. すべての書式指定子を処理した後、最終結果を出力します

実践例

1. 基本的な使い方

例

# 簡単な文字列出力
printf "Hello, World!\n"

# 変数を使った出力
name="Alice"
printf "Hello, %s\n" "$name"

実行と出力:

例

$ bash script.sh
Hello, World!
Hello, Alice

2. よく使う書式指定子

例

# 整数
printf "Decimal: %d\nHex: %x\nOctal: %o\n" 255 255 255

# 浮動小数点数
printf "Float: %f\nScientific: %e\n" 3.14159 3.14159

# 文字列
printf "Name: %s\n" "Bob"

# 文字
printf "First letter: %c\n" "A"

実行結果:

Decimal: 255
Hex: ff
Octal: 377
Float: 3.141590
Scientific: 3.141590e+00
Name: Bob
First letter: A

3. 書式制御

例

# フィールド幅と配置
printf "|%10s|\n|%-10s|\n" "right" "left"

# 数字の先頭ゼロ
printf "Year: %04d\n" 23

# 浮動小数点数の精度
printf "Pi: %.2f\n" 3.14159

実行結果:

|     right|
|left      |
Year: 0023
Pi: 3.14

4. 複数引数の処理

例

printf "%-10s %5d %8.2f\n" "Apple" 5 2.5 "Orange" 3 1.75

実行結果:

Apple          5     2.50
Orange         3     1.75

応用

1. テーブル出力の作成

例

#!/bin/bash

# ヘッダー
printf "%-15s %10s %10s %10s\n" "Item" "Quantity" "Price" "Total"

# 区切り線
printf "%-15s %10s %10s %10s\n" "---------------" "----------" "----------" "----------"

# データ行
printf "%-15s %10d %10.2f %10.2f\n" "Notebook" 3 2.50 7.50
printf "%-15s %10d %10.2f %10.2f\n" "Pen" 5 1.20 6.00
printf "%-15s %10d %10.2f %10.2f\n" "Eraser" 2 0.50 1.00

# 合計行
printf "%-15s %10s %10s %10.2f\n" "" "" "Total:" 14.50

出力結果:

Item            Quantity      Price      Total
--------------- ---------- ---------- ----------
Notebook               3       2.50       7.50
Pen                    5       1.20       6.00
Eraser                 2       0.50       1.00
                       Total:             14.50

2. プログレスバーの実装

例

#!/bin/bash

for i in {1..20}; do
    printf "\rProgress: [%-20s] %d%%" $(printf "%${i}s" | tr ' ' '#') $((i*5))
    sleep 0.1
done
printf "\n"

実行結果:徐々に伸びていくプログレスバーを表示します

3. 色付き出力

例

#!/bin/bash

RED='\033[0;31m'
GREEN='\033[0;32m'
NC='\033[0m' # No Color

printf "${RED}Error:${NC} Something went wrong\n"
printf "${GREEN}Success:${NC} Operation completed\n"

4. 書式付き出力

次に、printfの強力な機能を示すスクリプトを使います:

例

#!/bin/bash
# author:サンプル
# url:www.example.com
 
printf "%-10s %-8s %-4s\n"名前 性別 体重kg
printf "%-10s %-8s %-4.2f\n"郭靖 男66.1234
printf "%-10s %-8s %-4.2f\n"楊過 男48.6543
printf "%-10s %-8s %-4.2f\n"郭芙 女47.9876

スクリプトを実行すると、出力結果は次のようになります:

姓名     性别   体重kg
郭靖     男      66.12
杨过     男      48.65
郭芙     女      47.99

%s %c %d %fはすべて書式置換指定子です。%sは文字列を出力し、%dは整数を出力し、%cは1文字を出力し、%fは実数を小数形式で出力します。

%-10sは10文字の幅を意味し(-は左揃えを意味し、ない場合は右揃えになります)。すべての文字は10文字幅の中に表示され、足りない場合は自動的にスペースで埋められ、超えた場合も内容はすべて表示されます。

%-4.2fは小数としてフォーマットすることを意味し、.2は小数第2位まで保持することを意味します。

例

#!/bin/bash
# author:サンプル
# url:www.example.com
 
# format-stringは二重引用符
printf "%d %s\n" 1 "abc"

# 単一引用符と二重引用符は同じ効果
printf '%d %s\n' 1 "abc"

# 引用符なしでも出力可能
printf %s abcdef

# 書式は1つの引数しか指定していませんが、余分な引数もその書式に従って出力され、format-stringが再利用されます
printf %s abc def

printf "%s\n" abc def

printf "%s %s %s\n" a b c d e f g h i j

# argumentsがない場合、%sはNULLで置き換えられ、%dは0で置き換えられます
printf "%s and %d \n"

スクリプトを実行すると、出力結果は次のようになります:

1 abc
1 abc
abcdefabcdefabc
def
a b c
d e f
g h i
j  
 and 0

printfのエスケープシーケンス

シーケンス説明
\a警告文字。通常はASCIIのBEL文字
\bバックスペース
\c出力結果の末尾にある改行文字を抑制(表示しない)します(%b書式指定子で制御される引数文字列でのみ有効)。さらに、引数内に残っている文字、後続の引数、フォーマット文字列内に残っている文字はすべて無視されます。
\f改ページ(フォームフィード)
\n 改行
\rキャリッジリターン
\t水平タブ
\v垂直タブ
\\リテラルなバックスラッシュ文字
\ddd 1〜3桁の8進数値を表す文字。フォーマット文字列内でのみ有効
\0ddd1〜3桁の8進数値を表す文字

例

$ printf "a string, no processing:<%s>\n" "A\nB"
a string, no processing:<A\nB>

$ printf "a string, no processing:<%b>\n" "A\nB"
a string, no processing:<A
B>

$ printf "www.example.com \a"
www.example.com $                  #改行なし

まとめのポイント

重要ポイントの復習

概念 説明 例
基本構文 printf "format" args printf "%s" "hello"
書式指定子 %で始まり、データ型と書式を指定する %d(整数)、%f(浮動小数点数)
エスケープ文字 特殊文字の表現 \n(改行)、\t(タブ)
フィールド幅 出力の最小幅を制御する %10s(10文字幅)
精度制御 浮動小数点数の小数桁数 %.2f(小数第2位)

よく使う書式指定子の早見表

指定子 用途 入力例 出力例
%s 文字列 "text" text
%d 10進整数 255 255
%x 16進整数 255 ff
%f 浮動小数点数 3.14159 3.141590
%.2f 小数第2位 3.14159 3.14
%c 1文字 "A" A
%% パーセント記号 - %
その他の拡張