Padding string unicode dengan print bashf
Saya mencoba mengisi string Unicode dengan printf bash, dan melihatnya, sementara
printf "%2s" a
menghasilkan "a" yang diharapkan,
varian Unicode
printf "%2s" ä
menghasilkan "ä" yang ternyata tidak berisi. (zsh memberikan hasil yang diharapkan.)
Apa yang menyebabkan ini; dan bagaimana cara memasukkan string Unicode ke dalam bash?
Jawaban
bagaimana cara memasukkan string Unicode ke dalam bash?
Itu jauh di luar kemampuan bash. Jika Anda membatasi "string Unicode" ke ascii ++ (tidak ada karakter lebar ganda, tidak ada bidi, tidak ada tanda non-spasi, tidak ada dll), Anda dapat membuat juri-rig seperti:
% pad(){ printf '%*s%s\n' "$(($1-${#2}))" "" "$2"; }
% pad 2 €
€
Karakter ädikodekan dengan 2 byte dalam UTF-8, jadi Printf menganggapnya sebagai 2-padded.
Wc dapat menghitung karakter ( -m) dan byte ( -c) dari sebuah string. Nomor yang diberikan Printf kemudian [intended pad]+[bytes]-[chars]. Jadi saya telah menyusun pad.shskrip ini ,
#!/bin/sh
bytes=$(printf '%s' "$2" | wc -c)
chars=$(printf '%s' "$2" | wc -m)
n=$(($1+bytes-chars))
printf "%${n}s" "$2"
Dalam contoh eksekusi di bawah ini, saya telah menambahkan baris baru secara artifisial setelah setiap keluaran demi kejelasan.
$ sh pad.sh 10 abcdef abcdef $ sh pad.sh 10 äéßôçÈ
äéßôçÈ
bash berperilaku dengan benar dan program C.
#include <stdio.h>
main()
{
char foo[] = "ä";
printf("%2s\n", foo);
}
berperilaku sama.
Ini karena% s mengacu pada string berorientasi byte dan 'ä' dalam UTF-8 menghasilkan 2 byte.
Sejauh yang saya bisa uji, tidak ada cangkang lain yang berperilaku salah.
Hasil yang Anda harapkan bisa dilihat dengan sesuatu seperti:
printf '%2S\n' ä
tapi ini tidak didukung oleh cangkang mana pun yang saya uji.