Как вы повторяете 4-значный символ Unicode в Bash? - PullRequest
193 голосов
/ 02 марта 2009

Я хотел бы добавить череп и скрещенные кости Юникода в мою подсказку оболочки (в частности, «ЧЕРЕП И КРЕСТЫ» (U + 2620)), но я не могу понять магическое заклинание, чтобы заставить его эхом плевать, или любой другой 4-значный символ Unicode. Двузначные легко. Например, echo -e "\ x55",.

В дополнение к ответам ниже следует отметить, что, очевидно, ваш терминал должен поддерживать Unicode, чтобы вывод был тем, что вы ожидаете. gnome-терминал хорошо справляется с этой задачей, но он не обязательно включен по умолчанию.

В терминальном приложении macOS Перейдите в «Настройки» -> «Кодировки» и выберите «Юникод» (UTF-8).

Ответы [ 17 ]

3 голосов
/ 17 октября 2016

Если вы не возражаете против однострочности Perl:

$ perl -CS -E 'say "\x{2620}"'
☠

-CS включает декодирование UTF-8 на входе и кодирование UTF-8 на выходе. -E оценивает следующий аргумент как Perl, с включенными современными функциями, такими как say. Если вам не нужен перевод строки в конце, используйте print вместо say.

3 голосов
/ 19 апреля 2015

Встроенный printf (так же, как printf coreutils) знает escape-последовательность \u, которая принимает 4-значные символы Юникода:

   \uHHHH Unicode (ISO/IEC 10646) character with hex value HHHH (4 digits)

Тест с использованием Bash 4.2.37 (1):

$ printf '\u2620\n'
☠
3 голосов
/ 17 марта 2018

Извините за возрождение этого старого вопроса. Но при использовании bash очень легко создать кодовые точки Unicode из простого ввода ASCII, который даже не разветвляется вообще:

unicode() { local -n a="$1"; local c; printf -vc '\\U%08x' "$2"; printf -va "$c"; }
unicodes() { local a c; for a; do printf -vc '\\U%08x' "$a"; printf "$c"; done; };

Используйте его следующим образом для определения определенных кодовых точек

unicode crossbones 0x2620
echo "$crossbones"

или для выгрузки первых 65536 кодов Unicode в стандартный вывод (на моем компьютере это занимает менее 2 с. Дополнительное пространство - для предотвращения попадания определенных символов друг в друга из-за моноширинного шрифта оболочки):

for a in {0..65535}; do unicodes "$a"; printf ' '; done

или рассказать немного очень типичную историю родителей (для этого нужен Unicode 2010):

unicodes 0x1F6BC 32 43 32 0x1F62D 32 32 43 32 0x1F37C 32 61 32 0x263A 32 32 43 32 0x1F4A9 10

Пояснение:

  • printf '\UXXXXXXXX' печатает любой символ Unicode
  • printf '\\U%08x' number печатает \UXXXXXXXX с числом, преобразованным в шестнадцатеричное, затем передается другому printf для фактической распечатки символа Unicode
  • printf распознает восьмеричные (0oct), шестнадцатеричные (0xHEX) и десятичные (0 или числа, начинающиеся с 1 до 9) числа, поэтому вы можете выбрать, какое из представлений подходит лучше всего
  • printf -v var .. собирает вывод printf в переменную, без вилки (что чрезвычайно ускоряет процесс)
  • local variable существует, чтобы не загрязнять глобальное пространство имен
  • local -n var=other псевдонимы var до other, так что присвоение var изменяет other. Одна интересная часть здесь состоит в том, что var является частью локального пространства имен, а other является частью глобального пространства имен.
    • Обратите внимание, что в bash нет пространства имен local или global. Переменные хранятся в среде, и такие всегда глобальные. Local просто убирает текущее значение и восстанавливает его, когда функция снова выходит из режима ожидания. Другие функции, вызываемые из функции с local, все равно будут видеть «локальное» значение. Это принципиально иная концепция, чем у всех нормальных правил видимости, встречающихся в других языках (и то, что делает bash, очень мощно, но может привести к ошибкам, если вы программист, который не знает об этом).
2 голосов
/ 26 октября 2017

Легко с однострочником Python2 / 3:

$ python -c 'print u"\u2620"'    # python2
$ python3 -c 'print(u"\u2620")'  # python3

Результат:

2 голосов
/ 03 мая 2014

На основе вопросов переполнения стека Unix cut, удалите первый токен и https://stackoverflow.com/a/15903654/781312:

(octal=$(echo -n ☠ | od -t o1 | head -1 | cut -d' ' -f2- | sed -e 's#\([0-9]\+\) *#\\0\1#g')
echo Octal representation is following $octal
echo -e "$octal")

Вывод следующий.

Octal representation is following \0342\0230\0240
☠
1 голос
/ 11 апреля 2019

Вот список всех доступных смайликов Юникода:

https://en.wikipedia.org/wiki/Emoji#Unicode_blocks

Пример:

echo -e "\U1F304"
?

Для получения значения ASCII этого символа используйте hexdump

echo -e "?" | hexdump -C

00000000  f0 9f 8c 84 0a                                    |.....|
00000005

А затем используйте значения, указанные в шестнадцатеричном формате

echo -e "\xF0\x9F\x8C\x84\x0A"
?
0 голосов
/ 20 июля 2017

Если известно шестнадцатеричное значение символа Юникод

H="2620"
printf "%b" "\u$H"

Если известно десятичное значение символа Юникода

declare -i U=2*4096+6*256+2*16
printf -vH "%x" $U              # convert to hex
printf "%b" "\u$H"
...