web-dev-qa-db-ja.com

可変フォーマットでのprintfフォーマット-この変数は何を参照していますか?

私はbashでprintfのフォーマットを実験しており、次のコードに遭遇しました。

#/bin/bash
divider===============================
divider=$divider$divider

header="\n %-15s %8s %10s %11s\n"
format=" %-15s %08d %10s %11.2f\n"
width=55

printf "$header" "ITEM NAME" "ITEM ID" "COLOR" "PRICE"

printf "%$width.${width}s\n" "$divider"

printf "$format" \
Triangle 13  red 20 \
Oval 204449 "dark blue" 65.656 \
Square 3145 orange .7

私が興味を持っている行は言う行です:

printf "%$width.${width}s\n" "$divider"

その変数参照は何をしていますか?どういう意味ですか?

5
Allan

コード"%$width.${width}s\n"は、printfによる使用に適したフォーマット文字列を生成します

投稿したスクリプトでは、widthに値55が割り当てられているため、$width${width}の両方がbashによって55に展開されます。 printfへの最初のパラメーター全体が%55.55s\nに展開されます。これは%sという形式で、フィールド幅と精度指定子を使用して、正確に55文字で印刷するように要求します。この時点で変数dividerの値を指定すると、55の等号の行が出力されます。同じことを印刷するおそらくもっと簡単な方法はPerl -e 'print "=" x 55, "\n"'でした。

フィールド幅指定子の最も単純な形式は整数です。これはprintfに少なくともこの数の文字を使用して印刷するように要求します。印刷するために対応するパラメーターがこれよりも少ない文字を必要とする場合、出力にはスペースが左側に埋め込まれます。

精度指定子の最も単純な形式は、ドットの後に整数が続きます。%sに適用すると、印刷する最大文字数が設定されます。 (数値型の場合は意味が異なります。)

コメントに応じて、シェル変数の展開についても少し触れます(完全な説明は、bashのドキュメントで「パラメーターの展開」を検索して見つけることができます。 $ VAR vs $ {VAR}および引用するかしないか ):

  • 変数、たとえばxが設定されている場合、$xxの値に展開されます。その値に空白が含まれている場合、展開は数語になります。このため、上記のコードでは、たとえば"$format"が二重引用符で囲まれていることが重要です。これにより、展開が単一のWordになります(それ以外の場合、printfは最初のパラメーター%-15s、引き数%8sなどが続きます。フォーマット文字列全体を単一のパラメータとして受け取るのではありません)。

  • 変数xを展開するために、単に${x}の代わりに$xを記述することは許可されます。上記の場合、"${width}s"、そうする必要があります。なぜなら、もし"$widths"を書き込んだ場合、bashは変数widthsの値を取得しようとするため、設定されていないため、空の拡張で。

8
dhag