Auffüllen von Unicode-Strings mit Bashs printf
Ich habe versucht, eine Unicode-Zeichenfolge mit Bashs printf aufzufüllen, und habe das währenddessen gesehen
printf "%2s" a
ergibt das erwartete "a",
eine Unicode-Variante
printf "%2s" ä
ergibt ein überraschend ungepolstertes "ä". (zsh gibt das erwartete Ergebnis an.)
Was verursacht das? und wie soll ich Unicode-Strings in Bash auffüllen?
Antworten
Wie soll ich Unicode-Strings in Bash auffüllen?
Das geht weit über die Möglichkeiten von Bash hinaus. Wenn Sie "Unicode-Zeichenfolgen" auf ASCII ++ beschränken (keine Zeichen mit doppelter Breite, kein Bidi, keine Markierungen ohne Abstand, keine usw.), können Sie Folgendes wie folgt beurteilen:
% pad(){ printf '%*s%s\n' "$(($1-${#2}))" "" "$2"; }
% pad 2 €
€
Das Zeichen äwird in UTF-8 mit 2 Bytes codiert, daher nimmt Printf es für 2-aufgefüllt.
Wc kann die Zeichen ( -m) und Bytes ( -c) einer Zeichenfolge zählen. Die Nummer, die Printf geben soll, ist dann [intended pad]+[bytes]-[chars]. Also habe ich dieses pad.shSkript zusammengestellt,
#!/bin/sh
bytes=$(printf '%s' "$2" | wc -c)
chars=$(printf '%s' "$2" | wc -m)
n=$(($1+bytes-chars))
printf "%${n}s" "$2"
In der folgenden Beispielausführung habe ich aus Gründen der Übersichtlichkeit nach jeder Ausgabe künstlich Zeilenumbrüche hinzugefügt.
$ sh pad.sh 10 abcdef abcdef $ sh pad.sh 10 äéßôçÈ
äéßôçÈ
Bash verhält sich korrekt und das C-Programm
#include <stdio.h>
main()
{
char foo[] = "ä";
printf("%2s\n", foo);
}
verhält sich gleich.
Dies liegt daran, dass% s auf eine byteorientierte Zeichenfolge verweist und 'ä' in UTF-8 zu 2 Bytes führt.
Soweit ich testen konnte, verhält sich keine der anderen Schalen falsch.
Das erwartete Ergebnis kann mit folgenden Ergebnissen erzielt werden:
printf '%2S\n' ä
Dies wird jedoch von keiner der von mir getesteten Shells unterstützt.