首页 > 解决方案 > 我如何使用带有 unicode 字符的 sed

问题描述

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=

标签: linuxbashsedcommand-lineterminal

解决方案


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

  • 我们无法知道您使用的字符集和编码。您的语言环境已正确设置为 UTF-8,但您的终端和其他软件可能无法正确互操作。或许还可以查看Stack Overflowcharacter-encoding标签信息页面了解一些背景和诊断信息。
  • 即使您的系统和实用程序通常与 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~进行就地编辑但保存备份文件的选项。我几乎没有信心这会在没有一些修改的情况下立即生效,并且可能会得到您的澄清。


推荐阅读