我正在尝试使用echo命令转义以下代码,但我一直在获取实际的八位字节而不是表情符号。
另外我在哪里可以找到表情符号的八位字节值?我似乎总能找到UTF-8价值。
#!/usr/bin/env bash
UNICORN='\360\237\246\204\n'
FIRE=''
# this does not work when I run the script
printf '\360\237\246\204\n'
printf "Riding a ${UNICORN:Q}"
echo "Riding a ${UNICORN:Q}" #[Fails]: how to extract the actual emoji?
Run Code Online (Sandbox Code Playgroud)
EDIT_1:阅读评论后更新代码
#!/usr/bin/env bash
# Note: use hexdump -b to get one-bye octal display
UNICORN_UTF8=$'\360\237\246\204'
printf "U1F525\n"|hexdump -b # [ASK]: How to translate the return value to a valid UTF8 ?
FIRE_UTF8=$'\125\061\106\065\062\065\012'
echo "Riding a ${UNICORN_locale_encoding}"
echo "${UNICORN_UTF8} + ${FIRE_UTF8}"
Run Code Online (Sandbox Code Playgroud)
EDIT_2:发布最终代码。它有点工作。
#!/usr/bin/env bash
# Author:
# Usage:
# Note: use hexdump -b to get one-bye octal display of the emoji (needed for when ? computers use ? commandLine tools)
# Ex: printf "U1F525\n"|hexdump -v -e '"\\" 1/1 "%03o"' ; echo
UNICORN_UTF8=$'\360\237\246\204'
FIRE_UTF8=$'\xF0\x9F\x94\xA5'
LEAVE_SPACE=\^[a-zA-Z0-9_]*$\
echo "Riding an ${UNICORN_UTF8} ${LEAVE_SPACE} out of a ${FIRE_UTF8} ${LEAVE_SPACE} house."
Run Code Online (Sandbox Code Playgroud)
echo的语法是从标准C逃逸不同通过作为支持printf/ awk/ $'...'...
在标准echo语法中,您需要0在八进制序列(可以有 1 到 3 位数字)的前面加一个前导符¹:
echo '\0360\0237\0246\0204'
Run Code Online (Sandbox Code Playgroud)
请注意,要使用bash'secho内置xpg_echo函数,您需要启用选项²:
$ UNICORN_utf8_printf_format='\360\237\246\204'
$ UNICORN_utf8_echo='\0360\0237\0246\0204'
$ UNICORN_utf8=$'\360\237\246\204'
$ printf "$UNICORN_utf8_printf_format\n"
$ printf '%s\n' "$UNICORN_utf8"
$ shopt -s xpg_echo
$ echo "$UNICORN_utf8_echo"
Run Code Online (Sandbox Code Playgroud)
上面,只$UNICORN_utf8包含一个字符,用UTF8编码。其他包含反斜杠和数字的序列,旨在由相应的工具扩展。
该实用程序的%b格式printf也理解与echo. %b实际上是添加的,所以我们可以摆脱echo那些无法便携和可靠使用的东西。
$ printf '%b\n' "$UNICORN_utf8_echo"
Run Code Online (Sandbox Code Playgroud)
另见(在zsh和bash³):
UNICORN_locale_encoding=$'\U1f984'
Run Code Online (Sandbox Code Playgroud)
这会为您提供一个以区域设置编码的独角兽,即使区域设置的编码不是 UTF-8 并且也具有该字符(可能只有 GB18030,其中编码为$'\225\60\330\66'以及$'\360\237\246\204'将是??( \N{CJK UNIFIED IDEOGRAPH-9983}\N{<private use area-E6E9>})的编码) .
一些printf实现(包括 GNUprintf和 的printf内置zsh,ksh93以及bash(4.2 或更高版本)的最新版本)也在\UXXXXXXXX它们的格式参数(或%b除了 ksh93 的参数)中支持这些转义序列;GNU 需要 8 位数字。
¹GNU的coreutilsecho和busybox的echo支持\ooo用-e作为扩展(未时POSIXLY_CORRECT是在用于GNU环境echo)
² 其他选项是使用非标准-e选项,但是当posix和xpg_echo选项都启用时它不会工作,就像bash在 UNIX 合规模式下一样。
³ ksh93 和 mksh 也支持该语法,但无论语言环境的编码如何,都以 UTF-8 编码;在当前 (2018) 版本的 FreeBSD 中sh,您需要\U0001f984并且它仅适用于 UTF-8 语言环境。