如何在shell脚本中回显字符代码中的字符

时间:2015-04-16 11:01:40

标签: macos bash shell

如何在bash中将字符代码转换为字符?

我正在使用MAC并使用shell脚本。

我在脚本中有一个变量,例如:

$name="Cat \& Rat"

现在我想将此字符串作为

回显
Cat & Rat

我该怎么做?

5 个答案:

答案 0 :(得分:2)

预装在OSX上的

perl允许您可靠地解码HTML和XML实体:

perl -MHTML::Entities -C -pe 'decode_entities $_' <<<"Cat \&amp; Rat. 3&gt;2. 6&apos;"
# -> Cat \& Rat. 3>2. 6'

它识别252 HTML 4 entities plus &apos;,其中包括所有5个预定义的XML实体,并且在基于UTF-8的语言环境中(如OSX上的情况),将输入和输出视为UTF-8。 / p>

但保留\之前的& 如果您的所有&实例都是\ - 转义并且您想要删除反斜杠,只需使用Bash parameter expansion去除\实例,然后再将字符串传递给{{ 1}}:

perl

如果您想将所有 name="Cat \&amp; Rat" perl -MHTML::Entities -C -pe 'decode_entities $_' <<<"${name//\\&/&}" # -> Cat & Rat 转义序列转换为文字\<char>,请使用<char>(不含read):

-r

答案 1 :(得分:2)

如果你有GNU recode实用程序,并且只关心独立的XML实体,那么你可以这样做:

name="Cat \&amp; Rat"
recode XML <<<"$name"

通常,这将产生UTF-8的输出。它将处理&lt;&gt;&amp;&quot;&apos;以及数字实体(包括十六进制)。

答案 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//&amp;/&}"
}

实体代码地图显然不完整。添加您需要的那些,或者尝试以类似于权威参考的方式以编程方式构建完整的映射。 (我刚刚咨询了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)

我的纯bash 解决方案

我喜欢@tripleee's answer,还有另一种方法可以做到这一点,我们可以在下做一些技巧:

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 &quot;D&eacute;sir&eacute; &amp; Co&quot;'
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

当然,还有很多其他方式,比如

  • GNU recode
  • 的Perl
  • 的Python
  • Html解析器
  • 浏览器窗口 ...

更有用:我的 sed 脚本(在MacOS下测试)

您可能需要在MacOS下更改#!/usr/bin/sed -f shebang 行。

#!/bin/sed -f
s/&quot;/"/g; s/&amp;/\&/g; s/&lt;/</g; s/&gt;/>/g; s/&nbsp;/ /g; 
s/&iexcl;/¡/g; s/&cent;/¢/g; s/&pound;/£/g; s/&curren;/¤/g; 
s/&yen;/¥/g; s/&brvbar;/¦/g; s/&sect;/§/g; s/&uml;/¨/g; s/&copy;/©/g; 
s/&ordf;/ª/g; s/&laquo;/«/g; s/&not;/¬/g; s/&shy;/­/g; s/&reg;/®/g; 
s/&macr;/¯/g; s/&deg;/°/g; s/&plusmn;/±/g; s/&sup2;/²/g; s/&sup3;/³/g; 
s/&acute;/´/g; s/&micro;/µ/g; s/&para;/¶/g; s/&middot;/·/g; 
s/&cedil;/¸/g; s/&sup1;/¹/g; s/&ordm;/º/g; s/&raquo;/»/g; 
s/&frac14;/¼/g; s/&frac12;/½/g; s/&frac34;/¾/g; s/&iquest;/¿/g; 
s/&Agrave;/À/g; s/&Aacute;/Á/g; s/&Acirc;/Â/g; s/&Atilde;/Ã/g; 
s/&Auml;/Ä/g; s/&Aring;/Å/g; s/&AElig;/Æ/g; s/&Ccedil;/Ç/g; 
s/&Egrave;/È/g; s/&Eacute;/É/g; s/&Ecirc;/Ê/g; s/&Euml;/Ë/g; 
s/&Igrave;/Ì/g; s/&Iacute;/Í/g; s/&Icirc;/Î/g; s/&Iuml;/Ï/g; 
s/&ETH;/Ð/g; s/&Ntilde;/Ñ/g; s/&Ograve;/Ò/g; s/&Oacute;/Ó/g; 
s/&Ocirc;/Ô/g; s/&Otilde;/Õ/g; s/&Ouml;/Ö/g; s/&times;/×/g; 
s/&Oslash;/Ø/g; s/&Ugrave;/Ù/g; s/&Uacute;/Ú/g; s/&Ucirc;/Û/g; 
s/&Uuml;/Ü/g; s/&Yacute;/Ý/g; s/&THORN;/Þ/g; s/&szlig;/ß/g; 
s/&agrave;/à/g; s/&aacute;/á/g; s/&acirc;/â/g; s/&atilde;/ã/g; 
s/&auml;/ä/g; s/&aring;/å/g; s/&aelig;/æ/g; s/&ccedil;/ç/g; 
s/&egrave;/è/g; s/&eacute;/é/g; s/&ecirc;/ê/g; s/&euml;/ë/g; 
s/&igrave;/ì/g; s/&iacute;/í/g; s/&icirc;/î/g; s/&iuml;/ï/g; 
s/&eth;/ð/g; s/&ntilde;/ñ/g; s/&ograve;/ò/g; s/&oacute;/ó/g; 
s/&ocirc;/ô/g; s/&otilde;/õ/g; s/&ouml;/ö/g; s/&divide;/÷/g; 
s/&oslash;/ø/g; s/&ugrave;/ù/g; s/&uacute;/ú/g; s/&ucirc;/û/g; 
s/&uuml;/ü/g; s/&yacute;/ý/g; s/&thorn;/þ/g; s/&yuml;/ÿ/g;