ウェブサイト検索

BashのPrintfコマンドを例とともに解説


この記事では、Linuxでの例を用いて、Bash printfコマンドの基本的な使い方を説明します。この記事の最後には、Bashシェルスクリプトでprintfコマンドを使用することに慣れているでしょう。

Bashのprintfコマンド

Bash は、出力を端末に表示するために使用できる2種類のコマンドを提供します。1つは主にこの目的で使用される echo コマンドです。2つ目は printf コマンドです。

Printf は C 言語の printf 関数 に似ていますが、独自の機能セットがあります。echo と printf コマンドの主な違いは、printf が echo コマンドに比べてフォーマットや追加の機能を提供することです。

もしまだ echo コマンドを使ったことがない場合は、それについて詳しく説明している記事があるので、ぜひご覧ください。

  • LinuxにおけるBashのechoコマンドの説明と例

Printf はシェル組み込みですが、printf の外部コマンドも見つけることができます。組み込みコマンドは外部コマンドより優先されます。以下のように type コマンドを実行すると、この情報を取得できます。

$ type -a printf
printf is a shell builtin
printf is /usr/bin/printf
printf is /bin/printf

typeコマンドの詳細については、次のガイドを参照してください:

  • 初心者向けのタイプコマンドチュートリアルと例

外部バージョンのprintfを実行したい場合は、バイナリが存在するディレクトリのフルパスを指定する必要があります。

$ printf "Hello World\n" # SHELL BUILTIN
$ /usr/bin/printf "Hello World\n" # EXTERNAL VERSION OF PRINTF

組み込みコマンドと外部コマンド

Bash printf のヘルプを表示

前のセクションで述べたように、printf は bash の組み込みです。bash のマニュアルページを開き、printf セクションに移動する必要があります。

$ man bash
/printf → presss

Printf ヘルプ

次のコマンドを実行すると、bashのマニュアルページからprintfのヘルプセクションを表示することもできます。

$ man bash | less --pattern='^ *printf +['

printfコマンドの基本形

例を通して、printf と echo コマンドを比較して、共通点を理解します。

以下は printf コマンドのフォーマットです:

printf [-v var] format [arguments]

引数は printf に渡す必要があります。そうでなければ、下の画像に示されているように失敗します。

$ printf
$ echo $?

引数なしのPrintf

引数を渡して、もう一度 printf コマンドを実行します。以下の例から、私は改行文字である \n を追加したことがわかります。デフォルトでは、printf は echo コマンドのように改行を追加しないため、\n を追加する必要があります。

$ printf "Linux is fun to work with" # WITHOUT NEW LINE
$ printf "Linux is fun to work with\n" # WITH NEW LINE

改行文字付きのPrintf

変数とコマンドの解釈

printf 文内で任意の変数を囲んだり、コマンドを実行したりすることができます。この動作は echo コマンドと似ています。

$ VAR1="Linux"
$ printf "$VAR1 is fun to work with\n"

変数とコマンドの解釈

おすすめの読書:

  • Bashスクリプト – 変数の説明と例

シングルクオートとダブルクオートの挙動

引数をシングルクオートで囲むと、変数やコマンドは通常のテキストとして扱われます。これはechoコマンドでも同じ動作です。変数やコマンドを展開したい場合は、引数をダブルクオートで囲む必要があります。

$ printf '$VAR1 is fun to work with\n'
$ printf 'Today date = $(date)\n'

シングルクォートの使用

引用符なしで引数を渡すと、printf は最初の単語だけを引数として認識して表示します。したがって、printf の周りに引用符を使用することが必要です。

$ printf Today date = $(date)\n

引用符なしの引数

出力のリダイレクトとパイプ

デフォルトでは、printf は出力を stdout(ターミナル)に送ります。リダイレクト演算子 を使用して出力をファイルにリダイレクトしたり、パイプ演算子 と組み合わせてさらに処理することもできます。

# PRINT TO STDOUT
$ printf "Today date = $(date)\n"
# REDIRECT TO A FILE
$ printf "Today date = $(date)\n" > /tmp/tdy.txt
$ cat /tmp/tdy.txt
# PIPE
$ printf "Today date = $(date)\n" | grep -i -o IST

リダイレクションとパイピング

関連記事:

  • 事例で解説するBashのリダイレクション

出力を変数に割り当てる

時々、printf の出力を変数に保存して後で何らかの処理に使用したいと思うことがあります。通常、printf は括弧で囲んで実行し、コマンドを実行して出力を変数に代入します。

$ ZONE=$(printf "Today date = $(date)\n" | grep -i -o IST)
$ printf $ZONE

変数に割り当てられた出力

あるいは、printf と一緒に -v フラグを使用して、出力を変数に格納することができます。-v フラグの後に変数名を渡す必要があります。

$ printf -v TIME "Today date = $(date)\n"
$ echo $TIME

出力を変数に格納する

複数行のprintf文

印刷する行が複数ある場合は、テキストを二重引用符で囲むことができます。同様に、1行として大きな行を印刷する必要があり、コードの可読性のために複数行に分けて書きたい場合は、次の行を前の行の続きとして扱うために、各行の末尾にバックスラッシュを使用することができます。

$ printf "\n I am running PoP_OS
It is a great OS
With Great features\n"
$ printf "I am running pop_os \
It is a great OS \
With Great features\n"

複数行のprintf文

バックスラッシュでエスケープされた文字

printfで次のバックスラッシュでエスケープされた文字を使用できます。

  • 改行文字(\n)
  • 水平タブ (\t) と垂直タブ (\v)
  • バックスペース文字 (\b)
  • キャリッジリターン ()

例を挙げながら、一つずつ議論しましょう。

改行文字(\n)

すべての前のセクションで改行文字(\n)についてすでに見てきました。改行文字(\n)は新しい行を追加します。

$ printf "Today date = $(date)\n"

改行文字

水平タブ(\t)と垂直タブ(\v)

水平タブ文字と垂直タブ文字は、printf の引数にタブスペースを追加するために使用されます。

$ printf "Today date \t $(date)\n" # HORIZONTAL TAB
$ printf "Today date \v $(date)\n" # VERTICAL TAB

水平タブと垂直タブ

バックスペース文字 (\b)

バックスペース文字(\b)は1文字を削除します。これはキーボードのバックスペースキーを押すのと同じです。

$ printf "It's a rain\by day..\n"

バックスペース文字

キャリッジリターン ()

キャリッジリターン(\r)を使用すると、カーソルは最初の位置に戻ります。\r の後に続くものは、最初の位置から文字を置き換えます。

$ printf "It's a rain\by\r day..\n"

復帰

バックスラッシュ文字 (\) をエスケープする

特殊文字(\n、\t、\v、\b、)をエスケープして文字列として扱いたい場合は、先頭に二重バックスラッシュ(\\)を付けます。

$ printf "It's a rain\\by\\r day..\n"

バックスラッシュエスケープ

これまでに見たものは何であれ、同じ操作のセットをechoコマンドでも見つけることができます。もしすでにechoコマンドを知っているなら、この時点でprintfコマンドにも非常に慣れていることでしょう。

Printfのフォーマット指定子

フォーマット指定子は、printf に値を直接書き込む代わりに値を置き換える方法です。置き換えに使用される文字は多数あり、それぞれの文字は特定のデータ型を表します。指定子を使用する際には、% 記号を前につける必要があります。よく使われるフォーマット指定子をいくつか見てみましょう。

文字列指定子(%s)

もし printf の中に文字列を入れたい場合は、%s を使わなければなりません。以下の例を見てみましょう。私は printf 文を持っており、その中に値 "United" を置き換えたいです。そこで %s が使われます。これは文字列指定子であり、コマンドを実行すると値 "united" が %s の代わりに置き換えられます。

$ printf "++ Manchester %s has a strong lineup this season" "United"

文字列置換

置換引数はいくつでも渡すことができ、引数の中で同じ数の指定子を使用する必要があります。

$ printf "++ %s %s has a strong lineup this %s" "Manchester" "United" "season"

複数の引数を置き換える

もし指定子を減らして引数を増やしたらどうなるでしょうか?

以下の例を見てください。最初に1つの指定子を使用し、置換される3つの引数(文字列)を渡しました。printfの動作は、最初の引数を最初の指定子に置き換えることから始まり、他の指定子がないため、次の引数も再び最初の指定子に渡されます。このようにして、実際には正しくない3回の置換が行われ、私たちが求める結果にはなりません。

$ printf "++ %s United has a strong lineup this Season\n" "Manchester" "United" "season"

渡された引数が多すぎます

この動作が理にかなっている使用例もあります。以下の例を見てみましょう。私は特定のプレイヤーに歓迎メッセージを表示したく、彼らの名前を引数として渡しました。通常は名前のリストを配列に保存し、配列をループしてメッセージを表示することができます。しかし、ループの使用を避けつつ結果を達成する効果的な方法です。

$ printf "++ Welcome %s to manchester united\n" "Ronaldo" "Varane" "Jadon Sancho\n"
++ Welcome Ronaldo to manchester united
++ Welcome Varane to manchester united
++ Welcome Jadon Sancho to manchester united

単一の指定子に複数の引数

符号付き10進整数 (%d) と符号なし10進整数 (%u)

符号付き整数を置き換えるには、%d を使用します。

$ printf ">> Welcome %s to manchester united - You get shirt number - %d\n" "Ronaldo" 7 "Varane" 19 "Jadon Sancho" 25

符号付き整数

符号なし整数を置き換えるには、%u を使用します。

$ printf "UNSIGNED INTEGER = %u\n" 10

符号なし整数

整数以外のデータ型を置き換えようとすると、エラーが発生します。

$ printf ">> Ronaldo gets no %d\n" seven

誤ったデータ型を置き換える

浮動小数点数 (%f)

浮動小数点数を代入するには、%f を使用します。

$ printf "Integer 100 to floating-point %f\n" 100

浮動小数点置換

バックスラッシュのエスケープシーケンスを解釈する

バックスラッシュのエスケープシーケンスを引数として渡すことができ、%b を使用するとバックスラッシュのエスケープシーケンスを解釈して展開します。

$ printf "Welcome to %b Manchester united %b" "\v" "\n"

バックスラッシュのエスケープシーケンス

Printf の変換指示子

printf の出力をフォーマットするために使用できるオプションの変換修飾子があります。

%[flags][width][.precision]specifier

幅修飾子

幅修飾子は、変換における最小文字数を決定します。文字数がそれより少ない場合、以下のようにスペースが前に付加されます。

$ printf "%10s\n" "Ronaldo"

幅修飾子

上の画像を見ると、指定子(Ronaldo)は7文字で、幅を10に指定しています。この場合、幅10に合わせるためにスペースが追加されます。

また、フラグ修飾子を使用して配置の調整を行ったり、スペースの代わりにゼロを追加したりすることもできます。たとえば、出力を左揃えにする必要がある場合は、ハイフン(-)フラグ修飾子を追加することができます。

$ printf "%-10s\n" "Ronaldo"

整列

整数値および浮動小数点値の場合、ゼロ(0)フラグ修飾子を追加することで、スペースをゼロに置き換えることができます。

$ printf "%010d \n" 7

スペースをゼロに置き換える

精度修飾子

これは、出力する文字列、整数、浮動小数点の桁数を決定するために使用できるオプションのパラメータです。出力する桁数を決定するには、ドット(.)の後に整数を使用する必要があります。

以下の例を見てください。文字列指定子を使用し、精度修飾子を4に設定しています。

$ printf "%.7s\n" "Ronaldo has joined Manu"

文字列の精度修飾子

精度の整数値の代わりにアスタリスク(*)を渡すことができます。アスタリスクは、精度の値を固定するのではなく、精度の引数を受け入れます。

$ printf "%.*s\n" 7 "Ronaldo has joined Manu"

アスタリスク精度修飾子

結論

この記事では、Bashのprintfコマンドについてかなりの情報を取り上げました。printfを快適に使うには、この記事に示されたすべての例を練習してください。Printfは、この記事で示した例よりもはるかに強力なフォーマット機能を持っています。基本を理解していれば、使用例に応じてprintfを効率的に使用することができます。

関連記事:

  • バッシュスクリプト – 添字付き配列を例で解説
  • Bashスクリプト – 連想配列を例で解説
  • Bashスクリプト – WhileループとUntilループの例を用いた解説
  • バッシュスクリプト – forループを例付きで解説
  • Bashスクリプト – 関数の説明と例
  • 初心者のためのBashヒアドキュメントチュートリアル