Bash
printf
コマンドを使用すると
、
echo
コマンド
よりも細かい制御とより多くの書式設定オプションを使用して Linux ターミナル ウィンドウに書き込むことができます。
printf
の奇妙な癖も役に立つことがあります。
端末への書き込み
これは、プログラムを操作する際の最も基本的な部分の 1 つです。プログラムは画面に何かを書き込み、ユーザーはそれを読み取ります。 コマンドライン プログラムを できるだけ簡潔にするという Unix 由来および Linux で支持されている慣例を考慮しても、多くのプログラムは何か問題が発生した場合にのみターミナルに書き込みます。何が起こっているのか、何が起ころうとしているのか、あるいはたった今起こったのかをユーザーに伝えることは、プログラミングの基本的な基本要素です。
Bash シェルには
、ターミナル ウィンドウにテキストを書き込むことができる
echo
コマンドがあります。変数を処理し、文字列に変数が含まれている場合はその値を表示することができ、スクリプトまたはコマンド ラインで使用できます。では、なぜ
printf
存在するのでしょうか?
echo
はテキストの書き込み機能は含まれていませんか?さて、
printf
、文字列を端末ウィンドウに書き込むという単純な行為を超えた機能を提供します。これにより、出力を非常に柔軟にフォーマットでき、その他のトリックもあります。
Bash の
printf
コマンドは、
C 言語
の
printf
関数をモデルとしていますが、相違点もあります。 C を知っている場合は、これらの違いに注意する必要があります。
基本的な文字列の書き方
echo
と
printf
端末に文字列を書き込むときの違いを見てみましょう。
エコー ここにいくつかの言葉があります
printf ここにいくつかの言葉があります
echo
コマンドはすべての単語を出力しますが、
printf
最初の単語のみを出力します。また、
printf
によって出力される
改行
はありません。出力はコマンド プロンプトと直接一致します。しかし、まず第一に、
printf
すべての単語に対して動作するようにするには、単語を引用符で囲む必要があります。
エコー ここにいくつかの言葉があります
printf "ここにいくつかの言葉があります"
その方が良いです。すべての単語が出力されましたが、まだ新しい行が表示されません。これは、
printf
では、新しい行を要求した場合にのみ新しい行を取得できるためです。面倒に思えるかもしれませんが、これを含めるかどうかを決めることができます。
printf
に新しい行を発行させるには、文字列に「
\n
」を含める必要があります。これは「改行」エスケープ シーケンスです。
エコー ここにいくつかの言葉があります
printf "ここにいくつかの言葉があります\n"
改行を使用する場合もあれば、使用しない場合もあります。ここでは、一方の
printf
ステートメントで改行が使用され、もう一方の printf ステートメントでは改行が使用されていない場合を示します。
printf "ハウツー" && printf "オタク\n"
最初の
printf
新しい行を印刷しないため、2 番目の
printf
からの出力は「How-To」の直後の同じ行に配置されます。 2 番目の
printf
\n
を使用して新しい行を出力します。これにより、印刷されたテキストの下の行にコマンド プロンプトが表示されます。
その他のエスケープ文字
使用できるエスケープ文字をさらにいくつか紹介します。 「
\n
」が実際に動作しているのはすでに見ました。
- \n : 新しい行に移動します。
- \r : キャリッジリターンを印刷します。これにより、出力カーソルが現在の行の先頭に戻ります。
- \t : タブ文字を印刷します。
- \v : 垂直タブスペースを印刷します。
- \\ : バックスラッシュ文字を出力します。
- \” : 引用符文字を出力します。
- \b : バックスペース文字を出力します。
キャリッジ リターン エスケープ文字は、カーソルを現在の行の先頭に戻します。
printf "ハチミツは諸悪の根源です\rお金\n"
printf
コマンドは入力を左から右に処理します。文字列は、
printf
エスケープ文字「
\r
」に遭遇するまで、通常のテキストとして出力されます。出力カーソルは現在の行の先頭に戻ります。
文字列の処理は、「
\r
」文字の直後の文字から再開されます。残りを処理すると、
printf
「Money」を出力し、「Honey」という単語を上書きします。
引用符 ”
"
” は文字列を引用するために使用され、バックスラッシュ ”
\
” 文字はエスケープ シーケンスを示します。これらの文字を印刷する場合は、バックスラッシュを使用してエスケープする必要があります。これにより、
printf
それらの文字をリテラル文字として扱うように指示されます。
printf "これは \tTab、これは引用符 \"、そしてこの \\ はバックスラッシュです\n"
変数の使用
printf
での
変数の使用は、
echo
での使用と非常に似ています。この環境変数のような変数を含めるには、通常どおり、変数の前にドル記号「
$
」を付けます。
printf "ホーム ディレクトリ: $HOME\n"
フォーマット文字列
フォーマット文字列は、出力のフォーマットを定義する文字列です。操作対象の書式文字列の引数としてテキストやその他の値を指定します。
フォーマット文字列には、テキスト、エスケープ シーケンス、およびフォーマット指定子を含めることができます。形式指定子は、文字列、整数、文字など、予期される引数のタイプを
printf
指示します。
これらは最も一般的な形式指定子です。これらはすべて先頭にパーセント「
%
」記号が付いています。パーセント記号を出力するには、2 つのパーセント記号を一緒に使用します (「
%%
」)。
- %s : 文字列を出力します。
- %c : 1 文字を印刷します。
- %d : 整数を出力します。
- %f : 浮動小数点数を出力します。
- %u : 符号なし整数を出力します。
- %o : 値を 8 進数で出力します。
- %x : 値を 16 進数で小文字で出力します。
- %X : 値を 16 進数で大文字で出力します。
- %e : 浮動小数点数を科学表記法で小文字で出力します。
- %E : 浮動小数点数を科学表記法で大文字で出力します。
- %% : パーセント「%」記号を印刷します。
printf "ハウツー %s\n" "オタク"
printf "%s%s %s\n" "方法" "-To" "オタク"
最初のコマンドのフォーマット文字列には、独自のテキストが含まれています。文字列「Geek」を引数として
printf
に渡します。これは、「
%s
」形式指定子と一致し、それによって出力されます。フォーマット文字列と引数文字列の間にはスペースがあるだけであることに注意してください。 C では、それらを区切るためにカンマが必要ですが、Bash バージョンの
printf
ではスペースを使用するだけで十分です。
2 番目の書式文字列には、書式指定子と改行エスケープ シーケンスのみが含まれます。 3 つの文字列引数は、各 ”
%s
” 形式指定子によって順番に使用されます。繰り返しになりますが、C では各引数の間にカンマを入れる必要がありますが、Bash
printf
使用するとそれを忘れることができます。
さまざまなタイプの引数を出力するには、適切な形式指定子を使用するだけです。以下は、
printf
を使用して構築された簡単な数値変換ルーチンです。値 15 を 10 進数、8 進数、および 16 進数で出力します。
printf "12 月: %d\n10 月: %o\n16 進数: %x\n" 15 15 15
例が乱雑にならないように、少しトリミングしてみましょう。
printf "16 進数: %x\n" 15
私たちのほとんどは、16 進値が大文字で表示され、0x10 未満の値が先頭にゼロが付けられて表示されることに慣れています。これを実現するには、大文字の 16 進形式指定子「
%X
」を使用し、パーセント記号「
%
」と「
X
」文字の間に幅指定子を置きます。
これは、引数を出力するフィールドの幅を
printf
伝えます。フィールドにはスペースが埋め込まれます。この形式では、2 桁の値がパディングなしで出力されます。
printf "16 進数: %2X\n" 15
ここで、先頭にスペースを付けて出力される大文字の値が取得されます。 2 つのフィールドの前にゼロを置くことで、
printf
でフィールドにスペースの代わりにゼロを埋め込むことができます。
printf "16 進数: %02X\n" 15
精度指定子を使用すると、出力に含める小数点の数を設定できます。
printf "浮動小数点: %08.3f\n" 9.243546
これにより、出力がきちんと整列された結果の表を簡単に作成できます。この次のコマンドは、Bash
printf
の別の特徴も示しています。書式指定子の数よりも引数の数が多い場合、すべての引数が使い果たされるまで、引数はバッチで書式文字列に入力されます。一度に処理されるバッチのサイズは、書式文字列内の書式指定子の数です。 C では、
printf
関数呼び出し内の追加の引数は無視されます。
printf "浮動小数点: %8.3f\n" 9.243546 23.665 8.0021
幅と精度の指定子は文字列にも使用できます。このコマンドは、10 文字幅のフィールドに文字列を出力します。
printf "%10s %d\n" "コート" 7 "靴" 22 "傘" 3
デフォルトでは、値はフィールド内で右寄せされます。左寄せにするには、パーセント記号「
%
」のすぐ後ろにマイナス記号「
-
」を使用します。
printf "%-10s %d" "コート" 7 "靴" 22 "傘" 3
精度指定子を使用して、印刷される最大文字数を設定できます。幅フィールドの制限を示すためにコロン文字「
:
」を使用しています。 「傘」という言葉がどのように切り捨てられるかではありません。
printf ":%10.6s:\n" "コート" "靴" "傘"
printf ":%-10.6s:\n" "コート" "靴" "傘"
幅指定子は引数として渡すこともできます。数値指定子の代わりにアスタリスク「
*
」を使用し、幅を整数の引数として渡します。
printf "%*s\n" 20 "右端" 12 "中央" 5 "左端"
その他のトリックと癖
書式指定文字列内の書式指定子は、コマンド ラインで通常の引数として指定されるか、式の出力として生成されるかに関係なく、適切な型の値を処理します。
これは 2 つの数値の合計を出力します。
printf "23+32=%d\n" $((23+32))
このコマンドは、現在の作業ディレクトリ内のディレクトリの数を出力します。
printf "%d 個のディレクトリがあります\n" $(ls -d */ | wc -l)
この
printf
コマンドは、別のコマンドの呼び出しから返された文字列を出力します。
printf "現在のユーザー: %s\n" $(whoami)
文字列形式指定子「
%s
」が引数に指定されていない場合、
printf
何も出力しません。
printf "1 つ: %s 2 つ: %s\n" "アルファ"
文字列形式指定子「
%s
」に誤って数値が指定された場合、それが文字列であるかのように出力され、エラーは表示されません。 C の
printf
ではこれを試さないでください。非常に悪いことが起こります。プログラムはおそらくクラッシュします。しかし、Bash
printf
文句を言わずにそれを処理します。
printf "1 つ: %s 2 つ: %s\n" "アルファ" 777
整数形式指定子 ”
%d
” が引数を受け取らない場合、ゼロが出力されます。
printf "整数: %d\n"
整数形式指定子 ”
%d
” が誤って文字列引数を受け取った場合、Bash はエラー メッセージを出力し、
printf
ゼロを出力します。
printf "整数: %d\n" "7"
Unicode 番号または「コード ポイント」を使用すると、奇妙なシンボルが生成されることがあります。これらは、文字「u」とそれに続く Unicode 値を使用してエスケープされます。
printf "ユーロ記号: \u20AC\n"
引数文字列にエスケープ シーケンスを含めるには、書式文字列で ”
%s
” 文字列書式指定子ではなく、”
%b
” 書式指定子を使用する必要があります。
printf "%s" "\u20AC\n"
printf "%b" "\u20AC\n"
最初の
printf
ステートメントは Unicode 値を処理せず、改行エスケープ シーケンスを認識しません。 2 番目の
printf
ステートメントは、「
%b
」形式指定子を使用します。これにより、Unicode 文字が正しく処理され、新しい行が出力されます。
コース用の馬
場合によっては、ターミナル ウィンドウにテキスト
echo
だけで十分な場合があります。ただし、位置決めや書式設定を適用する必要がある場合には、
printf
最適なツールです。
printf "%b" "tha-" "tha-" "tha-" "以上です。\n"





