如何在bash中将字符代码转换为字符?
我正在使用MAC并使用shell脚本。
我在脚本中有一个变量,例如:
$name="Cat \& Rat"
现在我想将此字符串作为
回显Cat & Rat
我该怎么做?
答案 0 :(得分:2)
perl
允许您可靠地解码HTML和XML实体:
perl -MHTML::Entities -C -pe 'decode_entities $_' <<<"Cat \& Rat. 3>2. 6'"
# -> Cat \& Rat. 3>2. 6'
它识别252 HTML 4 entities plus '
,其中包括所有5个预定义的XML实体,并且在基于UTF-8的语言环境中(如OSX上的情况),将输入和输出视为UTF-8。 / p>
但保留\
之前的&
如果您的所有&
实例都是\
- 转义并且您想要删除反斜杠,只需使用Bash parameter expansion去除\
实例,然后再将字符串传递给{{ 1}}:
perl
如果您想将所有 name="Cat \& Rat"
perl -MHTML::Entities -C -pe 'decode_entities $_' <<<"${name//\\&/&}"
# -> Cat & Rat
转义序列转换为文字\<char>
,请使用<char>
(不含read
):
-r
答案 1 :(得分:2)
如果你有GNU recode
实用程序,并且只关心独立的XML实体,那么你可以这样做:
name="Cat \& Rat"
recode XML <<<"$name"
通常,这将产生UTF-8的输出。它将处理<
,>
,&
,"
和'
以及数字实体(包括十六进制)。
答案 2 :(得分:1)
在一般情况下,您可以使用简单的函数将SGML实体代码替换为它们所代表的字符。这是一个不完整的概念证明,仅限Bash 4。
unentitize () {
local str=$1
local -A map=([lt]='<' [gt]='>' [quot]='"' [apos]="'") # omit [amp]='&'
for entity in "${!map[@]}"; do
str=${str//&"$entity";/${map["$entity"]}}
done
echo "${str//&/&}"
}
实体代码地图显然不完整。添加您需要的那些,或者尝试以类似于权威参考的方式以编程方式构建完整的映射。 (我刚刚咨询了http://dev.w3.org/html5/html-author/charref,这绝不具有权威性。)
如果你不能使用Bash 4,这里是一个大致相当的Perl脚本。
perl -pe 'BEGIN { %h=(lt => "<", gt => ">", quot => q("),
apos => qq(\x27), amp => "&");
$re=join("|", keys %h) } s/&($re);/$h{$1}/g'
答案 3 :(得分:0)
只需正确分配变量
name='Cat & Rat'
echo "$name"
Cat & Rat
答案 4 :(得分:0)
我喜欢@tripleee's answer,还有另一种方法可以做到这一点,我们可以在bash下做一些技巧:
unentitize () {
local -A map=( [quot]='"' [amp]='&' [lt]='<' [gt]='>' [nbsp]=' '
[brvbar]='¦' [sect]='§' [uml]='¨' [copy]='©' [ordf]='ª' [laquo]='«'
[not]='¬' [shy]='' [reg]='®' [macr]='¯' [deg]='°' [plusmn]='±'
[frac12]='½' [frac34]='¾' # ...
[egrave]='è' [eacute]='é' [ecirc]='ê' [euml]='ë' [igrave]='ì'
[divide]='÷' [oslash]='ø' )
local mapidx=${!map[*]} string="$1" lhs wrd
mapidx=${mapidx// /|}
while lhs=${string%%&*($mapidx);*}
[ "${#lhs}" -ne "${#string}" ]
do
wrd=${string#$lhs&}
wrd=${wrd%%;*}
string=${string//&$wrd;/${map[$wrd]}}
done
echo "${string}"
}
请注意,该循环针对字符串中的实体,而不是针对 map的索引。
unentitize 'Store "Désiré & Co"'
Store "Désiré & Co"
地图列表略有缩短。我的脚本用于构建更完整的列表:
{
echo -n 'local -A map=( '
for i in {32..255};do
printf -v v "\\%03o" $i
printf -v v "%b" $v
s=$(recode lat1..u8 <<<$v)
o=$(recode lat1..html <<<$v)
[ "$o" ] && [ -z "${o#&*;}" ] && [ "${o%&#*}" ] && \
echo -n "[${o//*(&|;)}]='$s' "
done
echo ')'
} | fold -w 76 -s
当然,还有很多其他方式,比如
浏览器窗口 ...
或sed:
您可能需要在MacOS下更改#!/usr/bin/sed -f
的 shebang 行。
#!/bin/sed -f
s/"/"/g; s/&/\&/g; s/</</g; s/>/>/g; s/ / /g;
s/¡/¡/g; s/¢/¢/g; s/£/£/g; s/¤/¤/g;
s/¥/¥/g; s/¦/¦/g; s/§/§/g; s/¨/¨/g; s/©/©/g;
s/ª/ª/g; s/«/«/g; s/¬/¬/g; s/­//g; s/®/®/g;
s/¯/¯/g; s/°/°/g; s/±/±/g; s/²/²/g; s/³/³/g;
s/´/´/g; s/µ/µ/g; s/¶/¶/g; s/·/·/g;
s/¸/¸/g; s/¹/¹/g; s/º/º/g; s/»/»/g;
s/¼/¼/g; s/½/½/g; s/¾/¾/g; s/¿/¿/g;
s/À/À/g; s/Á/Á/g; s/Â/Â/g; s/Ã/Ã/g;
s/Ä/Ä/g; s/Å/Å/g; s/Æ/Æ/g; s/Ç/Ç/g;
s/È/È/g; s/É/É/g; s/Ê/Ê/g; s/Ë/Ë/g;
s/Ì/Ì/g; s/Í/Í/g; s/Î/Î/g; s/Ï/Ï/g;
s/Ð/Ð/g; s/Ñ/Ñ/g; s/Ò/Ò/g; s/Ó/Ó/g;
s/Ô/Ô/g; s/Õ/Õ/g; s/Ö/Ö/g; s/×/×/g;
s/Ø/Ø/g; s/Ù/Ù/g; s/Ú/Ú/g; s/Û/Û/g;
s/Ü/Ü/g; s/Ý/Ý/g; s/Þ/Þ/g; s/ß/ß/g;
s/à/à/g; s/á/á/g; s/â/â/g; s/ã/ã/g;
s/ä/ä/g; s/å/å/g; s/æ/æ/g; s/ç/ç/g;
s/è/è/g; s/é/é/g; s/ê/ê/g; s/ë/ë/g;
s/ì/ì/g; s/í/í/g; s/î/î/g; s/ï/ï/g;
s/ð/ð/g; s/ñ/ñ/g; s/ò/ò/g; s/ó/ó/g;
s/ô/ô/g; s/õ/õ/g; s/ö/ö/g; s/÷/÷/g;
s/ø/ø/g; s/ù/ù/g; s/ú/ú/g; s/û/û/g;
s/ü/ü/g; s/ý/ý/g; s/þ/þ/g; s/ÿ/ÿ/g;