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"