Riempire le stringhe Unicode con printf di bash
Ho provato a riempire una stringa Unicode con printf di bash e l'ho visto, mentre
printf "%2s" a
restituisce la "a" attesa,
una variante Unicode
printf "%2s" ä
restituisce una "ä" sorprendentemente non imbottita. (zsh dà il risultato atteso.)
Cosa causa questo; e come dovrei riempire le stringhe Unicode in bash?
Risposte
come dovrei riempire le stringhe Unicode in bash?
Questo è ben oltre le capacità di bash. Se stai limitando le "stringhe Unicode" ad ascii ++ (nessun carattere a doppia larghezza, nessun bidi, nessun segno di non spaziatura, no ecc.), Puoi giudicare qualcosa come:
% pad(){ printf '%*s%s\n' "$(($1-${#2}))" "" "$2"; }
% pad 2 €
€
Il carattere äè codificato con 2 byte in UTF-8, quindi Printf lo prende per 2-riempito.
Wc può contare i caratteri ( -m) e i byte ( -c) di una stringa. Il numero da dare a Printf è quindi [intended pad]+[bytes]-[chars]. Quindi ho assemblato questo pad.shscript,
#!/bin/sh
bytes=$(printf '%s' "$2" | wc -c)
chars=$(printf '%s' "$2" | wc -m)
n=$(($1+bytes-chars))
printf "%${n}s" "$2"
Nell'esempio di esecuzione riportato di seguito, ho aggiunto in modo artificiale i newline dopo ogni output per motivi di chiarezza.
$ sh pad.sh 10 abcdef abcdef $ sh pad.sh 10 äéßôçÈ
äéßôçÈ
bash si comporta correttamente e il programma C.
#include <stdio.h>
main()
{
char foo[] = "ä";
printf("%2s\n", foo);
}
si comporta lo stesso.
Questo perché% s si riferisce a una stringa orientata ai byte e 'ä' in UTF-8 restituisce 2 byte.
Per quanto ho potuto testare, nessuna delle altre shell si comporta in modo errato.
Il risultato che ti aspetti potrebbe essere visto con qualcosa del tipo:
printf '%2S\n' ä
ma questo non è supportato da nessuna delle shell che ho testato.