删除ascii字符并替换为非ascii

时间:2015-10-28 08:53:50

标签: ascii non-ascii-characters extended-ascii

我想删除一个ASCII字符然后我想用非ASCII替换它。我的代码是:

sed -e 's/[\d100\d130]/g' 

解释:我想用“135”(ASCII,十进制)替换“100”(ASCII,十进制)。简而言之,我想要替换2个字母,其中一个将删除。这段代码有效吗?

2 个答案:

答案 0 :(得分:1)

这不是有效的sed命令:

sed -e 's/[\d100\d135]/g'

也许像

sed -e 's/[\d100]/[\d135]/g'

在快速测试中,这个"有效":

echo 'd' | sed -e 's/[\d100]/[\d135]/g'

建议的tr命令是关闭的,但135转换为八进制207,例如

tr '\144' '\207'

在UTF-8系统中,您可能会遇到135的问题,因为它不是有效的单字节代码。 135的相应UTF-8编码使用两个字节,例如\ 302 \ 207

echo 'd' | sed -e 's/\d100/\d194\d135/g'

可能是OP的意图。使用我的语言环境en_US.UTF-8,它会生成UTF-8编码的135(在vi-like-emacs中显示为\u0087:这恰好是有效的 UTF-8 ,但不是可打印的字符,因为它实际上是Unicode中的控制字符)。如果有更多关于OP用于输出的信息,可以提供更好的建议。

答案 1 :(得分:1)

十进制100是“d”,135是扩展的ascii“ç”或cedilla。
将a设置为所有值:

a="$(printf "$(printf '\\x%x' {95..105} 135 135 135 {130..140} )")"

这两项工作都是:

echo "$a"| tr '\144' '\207'
echo "$a"| sed -e $'s/\144/\207/g'    # Note the $

如果要查看此字符,请写入文件,然后使用IBM850编码打开它。在具有该容量的文本编辑器中,您将看到(三次cedillaç,并且d也改变了):

_`abcçefghiçççéâäàåçêëèïî

UTF-8

对于utf-8,事情是不同的 UTF-8中的cedilla是十进制231(十六进制E7),并输出:

$ printf $'\U0E7'
ç

要使UTF-8的值高于127(7F)且高达255(FF)可能会变得棘手,因为Bash会错误解释某些值。此函数将允许从值转换为正确的字符:

function chr_utf8 {
    local val
    [[ ${2?Missing Ordinal Value} -lt 0x80000000 ]] || return 1

    if [[ ${2} -lt 0x100 && ${2} -ge 0x80 ]]; then

        # bash 4.2 incorrectly encodes
        # \U000000ff as \xff so encode manually
        printf -v val "\\%03o\%03o" $(( (${2}>>6)|0xc0 )) $(( (${2}&0x3f)|0x80 ))
    else
        printf -v val '\\U%08x' "${2}"
    fi
    printf -v ${1?Missing Dest Variable} ${val}
}

chr_utf8 a 231
echo "$a"

结论

解决方案实际上非常简单:

echo "aadddcc" | sed $'s/d/\U0E7/g'       # echo $'\U0E7' should output ç
aaçççcc

测试您从echo $'\U0E7'获得ç,如果没有,则需要上述功能。