Дополнение строк юникода с помощью bash printf

Это скорость шины, вы можете убедиться в этом, прочитав файл "скорость".

cs-server@:~/Downloads/logs$ cat /sys/bus/usb/devices/usb1/speed 
480
cs-server@:~/Downloads/logs$ 
cs-server@:~/Downloads/logs$ 
cs-server@:~/Downloads/logs$ lsusb -t
/:  Bus 02.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/10p, 5000M
/:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/16p, 480M
    |__ Port 6: Dev 2, If 0, Class=Human Interface Device, Driver=usbhid, 1.5M
    |__ Port 8: Dev 3, If 0, Class=Vendor Specific Class, Driver=ftdi_sio, 12M
cs-server@:~/Downloads/logs$ 
2
12.09.2020, 20:19
3 ответа

bash ведет себя правильно и программа на C

#include <stdio.h>
main()
{
        char foo[] = "ä";

        printf("%2s\n", foo);
}

ведет себя так же.

Это связано с тем, что %s относится к строке, ориентированной на байты, а 'ä' в UTF -8 приводит к 2 байтам.

Насколько я мог проверить, ни одна из других оболочек не ведет себя некорректно.

Ожидаемый результат можно увидеть с помощью чего-то вроде:

printf '%2S\n' ä

, но это не поддерживается ни одной из протестированных мной оболочек.

0
18.03.2021, 23:05

how am I supposed to pad Unicode strings in bash?

Это далеко за пределами возможностей bash. Если вы ограничиваете «строки Unicode» до ascii++ (без символов двойной ширины, без биди, без пробелов, отличных от -, без и т. д. ), вы можете -настроить что-то вроде:

% pad(){ printf '%*s%s\n' "$(($1-${#2}))" "" "$2"; }
% pad 2 €
 €
0
18.03.2021, 23:05

Символ äзакодирован двумя байтами в UTF -8, поэтому Printf принимает его за 2 -дополненных.

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 äéßôçÈ
    äéßôçÈ
2
18.03.2021, 23:05

Теги

Похожие вопросы