【问题标题】:How can i use sed with unicode character我如何使用带有 unicode 字符的 sed
【发布时间】:2020-02-03 00:55:30
【问题描述】:
function change() {
  for i in {0..28}
  do
    echo ",${cryp_data_letter[$i]}" "${org_data[$i]}"
    sed -i "s/,${cryp_data_letter[$i]}/${org_data[$i]}/g" "./temp.txt"
    #cat "./temp.txt"
  done
}

我有一个函数可以通过特定规则更改 temp.txt 中的某些字符,但某些字符(例如 ı、ğ、ö 等)会随着空字符串而更改。我想问题的原因是 UTF-8 那么我如何将 sed 与 unicode 一起应用?或任何其他建议 --> "sed -i "s/,${cryp_data_letter[$i]}/${org_data[$i]}/g" "./temp.txt""

这是给定的文件 temp.txt:

abc ğhıi
def
jkl
oöpr
uü vy z
çgm ns
şt

和输出:

IDK ,ğS,ıT
NMY
BOÜ
G,öHÇ
P,ü ÖF ,
,çUŞ ZĞ
,şV

顺便说一句,在返回过程中,我会将所有字母更改为小写,并在所有字母之前加上“,”,这样它就会变成 sed 之前:

,a,b,c ,ğ,h,ı,i
,d,e,f
,j,k,l
,o,ö,p,r
,u,ü ,v,y ,z
,ç,g,m ,n,s
,ş,t

地区:

LANG=en_US.UTF-8
LANGUAGE=en_US:en
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC=tr_TR.UTF-8
LC_TIME=tr_TR.UTF-8
LC_COLLATE="en_US.UTF-8"
LC_MONETARY=tr_TR.UTF-8
LC_MESSAGES="en_US.UTF-8"
LC_PAPER=tr_TR.UTF-8
LC_NAME=tr_TR.UTF-8
LC_ADDRESS=tr_TR.UTF-8
LC_TELEPHONE=tr_TR.UTF-8
LC_MEASUREMENT=tr_TR.UTF-8
LC_IDENTIFICATION=tr_TR.UTF-8
LC_ALL=

【问题讨论】:

  • 你能创建一个 MCVE 吗?例如,您可以将printf 'Hello,\xC3\xB6\n' > file; sed -i -e $'s/,\xC3\xB6/, world/' file; cat file 复制粘贴到您的终端并运行它以查看UTF-8 ,ö 已成功替换为, world。你能做一些我们可以复制粘贴到我们的终端来显示你的意思的东西吗? (你贴的代码没有声明cryp_data_letter或者创建temp.txt,所以没有人可以尝试调试)
  • 对不起,我添加了文件内容的解释,并且 cryp_data_letter 是一个保留 29 个字母字符的数组。 @thatotherguy
  • 另外 org_data 是 cryp_data_letter 的不同顺序,它们的大小相同。@thatotherguy
  • 请将locale 的输出添加到您的问题中。
  • 我添加了@Cyrus

标签: linux bash sed command-line terminal


【解决方案1】:

这里有多个问题,可能每个单独或组合导致您的问题。

  • 我们无法知道您使用的字符集和编码。您的语言环境已正确设置为 UTF-8,但您的终端和其他软件可能无法正确互操作。或许还可以查看Stack Overflow character-encoding tag info page 了解一些背景和诊断信息。
  • 即使您的系统和实用程序通常与 UTF-8 兼容,也不能保证您的 sed 是兼容的。许多sed 变体仍然对Unicode 视而不见,并且对于具体行为应该是什么也没有稳定的建议。有时切换到不同的语言是有意义的;许多琐碎的sed 脚本可以很容易地移植到perl -CSD -p 下运行,只需很少或不需要更改。
  • 即使其他一切工作正常,Unicode 也提供了多种方法来表示许多重音字符。如果您的数据包含 ö 作为单个代码点 U+00E6 但您的脚本包含相应的分解序列,反之亦然,您的 sed 脚​​本(可能)不会替换替代表示。寻找 Unicode 规范化。

除此之外,如果第二点就足够了,那么下面的方法实际上可能会起作用。

perl -CSD -pi~ e 'tr/AEİR...FJ/ABCÇ...YZ/' ./temp.txt

注意-i~ 选项可进行就地编辑但保存备份文件。我几乎没有信心这会在没有一些修改和可能来自您方面的澄清的情况下立即生效。

【讨论】:

  • 并不是真的要检查社区 Wiki,但是哦 :-)
【解决方案2】:

很抱歉没有回答,但我无法重现您的问题。

这是您在一个完全独立的脚本中的代码(下次请自己执行此操作):

#!/bin/bash

if [[ ö != $'\xC3\xB6' ]]
then
  echo "You didn't save this file as UTF-8"
  exit 1
fi

function change() {
  for i in {0..28}
  do
#    echo ",${cryp_data_letter[$i]}" "${org_data[$i]}"
    sed -i "s/,${cryp_data_letter[$i]}/${org_data[$i]}/g" "./temp.txt"
    #cat "./temp.txt"
  done
}

# Shift all characters one letter ahead in the alphabet
cryp_data_letter=({a..z} ğ ö ı)
org_data=({b..z} ğ ö ı a)

# Create the file as you say it is before the sed
cat > temp.txt << "EOF"
,a,b,c ,ğ,h,ı,i
,d,e,f
,j,k,l
,o,ö,p,r
,u,ü ,v,y ,z
,ç,g,m ,n,s
,ş,t
EOF

change

cat temp.txt

当我运行./testscript 时,我得到了这个输出:

bcd öiaj
efg
klm
pıqs
v,ü wz ğ
,çhn ot
,şu

如您所见,包括ö 和ğ 在内的字母正在被替换和插入就好了。

【讨论】:

    猜你喜欢
    • 2022-01-15
    • 2018-07-02
    • 1970-01-01
    • 2020-05-23
    • 2017-08-25
    • 1970-01-01
    • 2018-11-14
    • 1970-01-01
    • 2019-11-14
    相关资源
    最近更新 更多