Заполнение строк Unicode с помощью printf bash
Я попытался дополнить строку Unicode с помощью printf bash и увидел это, в то время как
printf "%2s" a
дает ожидаемую "а",
вариант Unicode
printf "%2s" ä
дает удивительно неполную букву «ä». (zsh дает ожидаемый результат.)
Что вызывает это; и как я должен заполнять строки Unicode в bash?
Ответы
как я должен заполнять строки Unicode в bash?
Это выходит за рамки возможностей bash. Если вы ограничиваете «строки Unicode» до ascii ++ (без символов двойной ширины, без двунаправленного текста, без знаков пробела и т. Д.), Вы можете придумать что-то вроде:
% pad(){ printf '%*s%s\n' "$(($1-${#2}))" "" "$2"; }
% pad 2 €
€
Символ äкодируется двумя байтами в UTF-8, поэтому Printf принимает его как заполненный двумя байтами.
Wc может подсчитывать символы ( -m) и байты ( -c) в строке. Число, которое нужно дать Printf, будет тогда [intended pad]+[bytes]-[chars]. Итак, я собрал этот pad.shсценарий,
#!/bin/sh
bytes=$(printf '%s' "$2" | wc -c)
chars=$(printf '%s' "$2" | wc -m)
n=$(($1+bytes-chars))
printf "%${n}s" "$2"
В приведенном ниже примере выполнения я специально добавил новые строки после каждого вывода для ясности.
$ sh pad.sh 10 abcdef abcdef $ sh pad.sh 10 äéßôçÈ
äéßôçÈ
bash ведет себя правильно, а программа C
#include <stdio.h>
main()
{
char foo[] = "ä";
printf("%2s\n", foo);
}
ведет себя так же.
Это связано с тем, что% s относится к байтовой строке, а «ä» в UTF-8 дает 2 байта.
Насколько я мог проверить, ни одна из других оболочек не ведет себя некорректно.
Ожидаемый результат можно увидеть примерно так:
printf '%2S\n' ä
но это не поддерживается ни одной из протестированных мною оболочек.