【问题标题】:remove ascii character and replace with non-ascii删除 ascii 字符并替换为非 ascii
【发布时间】:2015-10-28 08:53:50
【问题描述】:

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

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

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

【问题讨论】:

  • 使用tr:tr '\144' '\206'
  • 它不起作用。我试过了。 @gniourf_gniourf
  • 不起作用是什么意思? (你收到错误了吗?d 不是被替换了吗?)
  • d 没有被替换。@gniourf_gniourf
  • (除了明显的拼写错误——应该是tr '\144' '\207'——参见Thomas Dickey 的回答)。这不会编辑您的文件……这是您所期望的吗?

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


【解决方案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'
ç

要获得高于 127 (7F) 和高达 255 (FF) 的值的 UTF-8 可能会变得棘手,因为 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'得到一个ç,如果没有,你需要上面的函数。

【讨论】:

  • 当我尝试所有字母时,我的输出:abc�efghijklmnopqrstuvwxyz{|}~�������������
  • 你需要一个 cedilla 吗?那是utf-8 decimal 231
【解决方案2】:

这不是一个有效的 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 用于输出的更多信息,可以提供更好的建议。

【讨论】:

  • 当我运行时,我的输出是“?”。为什么?
  • s/// 运算符的右轴中,我不确定OP 是否需要方括号;而且它们在 lhs 中也没有用:s/\d100/\d135/g.
  • 正如我所说:在 UTF-8 中,这不是一个有效字符。我留下了方括号,但同意它们是不必要的。
  • 它仍然没有从我的 OP 中排除。 ://
  • 当我尝试所有字母时,我的输出:abc�efghijklmnopqrstuvwxyz{|}~�������������
猜你喜欢
  • 2018-07-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多