Padding string unicode dengan print bashf

Sep 13 2020

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

crackpot Sep 13 2020 at 00:02

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 €
 €
Quasímodo Sep 13 2020 at 00:06

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 äéßôçÈ
    äéßôçÈ
schily Sep 12 2020 at 23:48

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.