POSIX требует printf
% - 20 секунд
для подсчета этих 20 в терминах байтов не символов , хотя это не имеет особого смысла, поскольку printf
предназначен для напечатайте текст , отформатированный (см. обсуждение в списках рассылки Austin Group (POSIX) и bash
).
Встроенная функция printf
bash
и большинство других оболочек POSIX учитывают это.
zsh
игнорирует это глупое требование (даже в эмуляции sh
), поэтому printf
работает так, как и следовало ожидать. То же самое для встроенной функции printf
из fish
(не POSIX-подобной оболочки).
Символ ü
(U + 00FC) при кодировании в UTF-8 состоит из двух байтов (0xc3 и 0xbc), что объясняет расхождение.
$ printf %s 'Früchte und Gemüse' | wc -mcL
18 20 18
Эта строка состоит из 18 символов и имеет ширину 18 столбцов ( -L
является расширением GNU wc
, чтобы сообщить ширину отображения самой широкой строки во входных данных), но закодирован на 20 байтах.
В zsh
или fish
текст будет выровнен правильно.
Теперь есть также символы с нулевой шириной (например, объединяющие символы, такие как U + 0308, объединяющая диареза) или имеющие двойную ширину, как во многих азиатских скриптах (не говоря уже о управляющих символах, таких как Tab) и даже zsh
не выровнял их должным образом.
Пример в zsh
:
$ printf '%3s|\n' u ü $'u\u308' $'\u1100'
u|
ü|
ü|
ᄀ|
В bash
:
$ printf '%3s|\n' u ü $'u\u308' $'\u1100'
u|
ü|
ü|
ᄀ|
ksh93
имеет спецификацию формата % Ls
для подсчета ширины в с точки зрения отображения ширины.
$ printf '%3Ls|\n' u ü $'u\u308' $'\u1100'
u|
ü|
ü|
ᄀ|
Что все еще не работает , если текст содержит управляющие символы, такие как TAB (как это могло быть? printf
должен был бы знать, как далеко находятся позиции табуляции в устройстве вывода. и с какой позиции начинается печать). Он случайно работает с символами возврата (например, в выводе roff
, где X
(полужирный X
) записывается как X \ bX
), хотя как ksh93
считает, что все управляющие символы имеют ширину -1
.
В качестве других вариантов вы можете попробовать:
printf '%s\t|\n' u ü $'u\u308' $'\u1100' | expand -t3
Это работает с некоторыми реализациями expand
(но не с GNU).
В системах GNU вы можете использовать GNU awk
, у которого printf
подсчитывается в символах (не в байтах, не в ширине дисплея, поэтому все равно не подходит для ширины 0 или 2- ширины символов, но подходит для вашего примера):
gawk 'BEGIN {for (i = 1; i < ARGC; i++) printf "%-3s|\n", ARGV[i]}
' u ü $'u\u308' $'\u1100'
Если вывод идет на терминал, вы также можете использовать escape-последовательности для позиционирования курсора. Нравится:
forward21=$(tput cuf 21)
printf '%s\r%s%s\n' \
"Früchte und Gemüse" "$forward21" "foo" \
"Milchprodukte" "$forward21" "bar" \
"12345678901234567890" "$forward21" "baz"
Вы можете исключить пакеты с помощью этой команды:
sudo zypper addlock {package name}
Итак, в вашем случае это должно выглядеть так:
sudo zypper addlock kdeconnect-kde