次の出力を試してください|Ü| X|
。
echo 'Ü X' | awk '{printf("|% 2s|% 2s|\n", $1, $2)}'
明らかにawk
文字長ではなくバイト長が計算されるため、Ü
数は2で、左マージンは必要ありませんX
。
awk
重要なモードで実行できますか?特徴バイト長ではなくパターン長%<count>s
printf
ですか?
これ同じbash
問題がありますprintf
。答えが違うことを願っています。 「libc printfへのパス」:-/
私は〜だったいいえgawk
バージョンに関係なく使用Ubuntu22.04(Jammy Jellyfish)がすでにインストールしています。gawk
最近はインストールできないと思いました:-/
答え1
GNU awk(他のawkバリエーションがあるかもしれません):
$ echo 'Ü X' | LC_ALL='en_US.UTF-8' awk '{printf "|% 2s|% 2s|\n", $1, $2}'
| Ü| X|
バッシュ 3.0+(調整する必要がある他のシェルがあるかもしれません):
$ LC_ALL='en_US.UTF-8' a='Ü' b='X'
$ printf '|%*s%s|%*s%s|\n' "$(( 2 - ${#a} ))" '' "$a" "$(( 2 - ${#b} ))" '' "$b"
| Ü| X|
bashのバージョンは、バージョンが発生する環境だけでなくLC_ALL
実行中のシェルでも設定する必要があるため、呼び出しシェルでそれを変更したくない場合は、保存/復元する必要があります。つまり、またはサブシェルですべての操作を実行します。つまり、 。${#a}
printf
awk
LC_ALL
o="$LC_ALL"; LC_ALL='en_US.UTF-8' ... "$b"; LC_ALL="$o"
( LC_ALL='en_US.UTF-8' ... "$b" )
説明する:
~からGNU awkドキュメント:
-b --characters-as-bytes
gawkがすべての入力データを単一バイト文字として扱うようにします。また、print または printf を使用して作成されたすべての出力は、シングルバイト文字として扱われます。
通常、gawkはPOSIX標準に準拠し、現在のロケールに従って入力データを処理しようとします(参照:あなたの場所はさまざまです)。これには通常、マルチバイト文字をワイド文字に(内部的に)変換することが含まれ、入力データに有効なマルチバイト文字が含まれていないと問題や混乱が発生する可能性があります。このオプションは、gawkに「私のデータを削除してください!」と通知する簡単な方法です。
適切なロケールセットでGNU awk 5.2.2を使用すると、マルチバイト文字を単一のマルチバイト文字として扱います。
$ echo 'Ü X' | LC_ALL='en_US.UTF-8' awk '{printf "|% 2s|% 2s|\n", $1, $2}'
| Ü| X|
他のロケールを使用または使用している間、-b
すべての入力は単一バイト文字として扱われます。
$ echo 'Ü X' | LC_ALL='C' awk '{printf "|% 2s|% 2s|\n", $1, $2}'
|Ü| X|
$ echo 'Ü X' | awk -b '{printf "|% 2s|% 2s|\n", $1, $2}'
|Ü| X|
使用時の-b
結果はロケールとは無関係です。
$ echo 'Ü X' | LC_ALL='en_US.UTF-8' awk -b '{printf "|% 2s|% 2s|\n", $1, $2}'
|Ü| X|
$ echo 'Ü X' | LC_ALL='C' awk -b '{printf "|% 2s|% 2s|\n", $1, $2}'
|Ü| X|
〜のように@StéphaneChazelasで言及コメント、望むよりprintfが分音符を「縮小」するのはなぜですか?printf
シェルの関連動作の場合@Léa Grisの返信bash 3.0以降でフォーマットされた出力が正しくなるように文字数を取得することをお勧めします。
$ a='Ü' b='X' LC_ALL='en_US.UTF-8'
$ printf '|%*s%s|%*s%s|\n' "$(( 2 - ${#a} ))" '' "$a" "$(( 2 - ${#b} ))" '' "$b"
| Ü| X|
この機能はロケール設定の影響も受けます。
$ LC_ALL='C'
$ printf "|%*s%s|%*s%s|\n" "$(( 2 - ${#a} ))" '' "$a" "$(( 2 - ${#b} ))" '' "$b"
|Ü| X|
また、見ることができますBashの文字列長Bashから文字の長さを取得する方法に関する追加情報。