POSIXが必要と printf
のの%-20s
の面でそれらの20を数えるバイトない文字としてそれはほとんど意味がないにもかかわらず、printf
印刷することであるテキストを(議論を参照フォーマットされた、オースティン・グループで(POSIX)とbash
メーリングリストを)。
printf
組み込みbash
や他のほとんどのPOSIXシェルはそれを尊重します。
zsh
(そのsh
エミュレーションであっても)その馬鹿げた要件を無視するので、printf
期待どおりに動作します。(POSIXのようなシェルではない)のprintf
組み込みについても同じですfish
。
ü
UTF-8でエンコードされた文字(U + 00FC)は、矛盾を説明する2バイト(0xc3との0xBC)で構成されています。
$ printf %s 'Früchte und Gemüse' | wc -mcL
18 20 18
この文字列は18文字で構成され、18列幅(入力の最も広い行の表示幅を報告-L
するGNU wc
拡張機能)ですが、20バイトでエンコードされます。
ではzsh
またはfish
、テキストが正しく整列されるだろう。
現在、0幅(U + 0308などの文字の組み合わせなど)や、多くのアジア系スクリプト(Tabなどの制御文字は言うまでもなく)のような倍幅を持つ文字もzsh
あり、整列しませんそれらを適切に。
例zsh
:
$ printf '%3s|\n' u ü $'u\u308' $'\u1100'
u|
ü|
ü|
ᄀ|
でbash
:
$ printf '%3s|\n' u ü $'u\u308' $'\u1100'
u|
ü|
ü|
ᄀ|
ksh93
には、表示幅の%Ls
観点から幅をカウントする形式仕様があります。
$ printf '%3Ls|\n' u ü $'u\u308' $'\u1100'
u|
ü|
ü|
ᄀ|
テキストにTABなどの制御文字が含まれている場合、それはまだ機能しません(printf
出力デバイスのタブストップの間隔と印刷を開始する位置を知る必要があります)。これは、(のようにバックスペース文字を誤って作業を行いroff
出力X
(太字X
のように書かれている)X\bX
としても)ksh93
すべての制御文字は幅を有するものとして考えます-1
。
他のオプションとして、あなたは試すことができます:
printf '%s\t|\n' u ü $'u\u308' $'\u1100' | expand -t3
これはいくつかのexpand
実装で動作します(GNUではありません)。
GNUシステムawk
でprintf
は、char でカウントするGNU を使用できます(バイトではなく、表示幅ではないため、0幅または2幅の文字では問題ありませんが、サンプルでは問題ありません)。
gawk 'BEGIN {for (i = 1; i < ARGC; i++) printf "%-3s|\n", ARGV[i]}
' u ü $'u\u308' $'\u1100'
出力が端末に送られる場合は、カーソルポジショニングエスケープシーケンスも使用できます。好む:
forward21=$(tput cuf 21)
printf '%s\r%s%s\n' \
"Früchte und Gemüse" "$forward21" "foo" \
"Milchprodukte" "$forward21" "bar" \
"12345678901234567890" "$forward21" "baz"