Bash'ın printf ile unicode dizelerini doldurma
Bir Unicode dizesini bash'ın printf ile doldurmayı denedim ve bunu gördüm.
printf "%2s" a
beklenen "a" değerini verir,
bir Unicode varyantı
printf "%2s" ä
şaşırtıcı bir şekilde dolgusuz bir "ä" verir. (zsh, beklenen sonucu verir.)
Buna ne sebep olur; ve Unicode dizelerini bash'ta nasıl dolduracağım?
Yanıtlar
bash'ta Unicode dizelerini nasıl dolduracağım?
Bu, bash'ın yeteneklerinin çok ötesinde. "Unicode dizelerini" ascii ++ ile sınırlıyorsanız (çift genişlikli karakterler yok, bidi yok, boşluk bırakmayan işaretler yok, vb.), Aşağıdaki gibi bir jüri donanımı uygulayabilirsiniz:
% pad(){ printf '%*s%s\n' "$(($1-${#2}))" "" "$2"; }
% pad 2 €
€
Karakter äUTF-8'de 2 bayt ile kodlanmıştır, bu nedenle Printf onu 2-dolgulu olarak alır.
Wc, bir dizenin karakterlerini ( -m) ve baytlarını ( -c) sayabilir . Printf'e verilecek numara o zaman [intended pad]+[bytes]-[chars]. Bu yüzden bu pad.shsenaryoyu bir araya getirdim ,
#!/bin/sh
bytes=$(printf '%s' "$2" | wc -c)
chars=$(printf '%s' "$2" | wc -m)
n=$(($1+bytes-chars))
printf "%${n}s" "$2"
Aşağıdaki örnek uygulamada, netlik uğruna her çıktıdan sonra yapay olarak yeni satırlar ekledim.
$ sh pad.sh 10 abcdef abcdef $ sh pad.sh 10 äéßôçÈ
äéßôçÈ
bash düzgün davranır ve C programı
#include <stdio.h>
main()
{
char foo[] = "ä";
printf("%2s\n", foo);
}
aynı şekilde davranır.
Bunun nedeni,% s'nin bayt yönelimli bir dizgeye başvurması ve UTF-8'deki 'ä' ifadesinin 2 bayt ile sonuçlanmasıdır.
Test edebildiğim kadarıyla, diğer mermilerin hiçbiri yanlış davranmıyor.
Beklediğiniz sonuç aşağıdaki gibi bir şeyle görülebilir:
printf '%2S\n' ä
ancak bu, test ettiğim kabukların hiçbiri tarafından desteklenmiyor.