关于文本文件编码的混淆以及如何在不同的编码方法之间进行转换?

时间:2017-03-31 22:17:12

标签: linux encoding sed utf-8 ascii

我有一个文本文件f.txt,编码为UTF-8,如下所示:

chengs-MBP:test cheng$ cat f.txt 
Wіnd
like
chengs-MBP:test cheng$ FILE -I f.txt 
f.txt: text/plain; charset=utf-8

但是,此文件Windlike中的这两个字是不同的,因为like可以通过grep命令查找,而Wind则不能,它困惑了我:

chengs-MBP:test cheng$ cat f.txt | grep like
like
chengs-MBP:test cheng$ cat f.txt | grep Wind
chengs-MBP:test cheng$  

我想通过us-ascii命令将此文件转换为iconv,但我失败了:

chengs-MBP:test cheng$ iconv -f UTF-8 -t US-ASCII f.txt > new.txt
conv: f.txt:1:0: cannot convert

我的目标是将此文件转换为一种格式,可以通过grepsed查找此文件中的所有字词......这就是全部。

2 个答案:

答案 0 :(得分:0)

UTF-8是Unicode字符集的编码。一些Unicode字符在类似的子集中,有时统称为“confusables”。所以,

$useragent= "curl/7.39.0";
curl_setopt($ch,CURLOPT_USERAGENT, $useragent);

会查找LATIN SMALL LETTER I,而

f.txt | grep "Wind"

会查找CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I。你可以把它写成

f.txt | grep "Wіnd"

由于它不是ASCII字符集的成员,因此无法以ASCII编码。

如果您想更进一步,我建议您不要放弃UTF-8作为文本文件编码,但您可能希望将可混淆的字母音译为Basic Latin或使用处理音译的搜索库作为一个功能。 f.txt | grep "W\xD1\x96nd" 只是为您提供您所要求的内容。

答案 1 :(得分:0)

在我的示例中,我将在'Wind'一词中使用'i',CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I为十六进制d196

要查找符号十六进制表示,您可以使用xxdhexdump

$ xxd -g 1 f.txt 
00000000: 57 d1 96 6e 64 0a 6c 69 6b 65 0a                 W..nd.like.

$ hexdump -C f.txt 
00000000  57 d1 96 6e 64 0a 6c 69  6b 65 0a                 |W..nd.like.|

如您所见,在右侧,在ASCII部分中,UTF符号被点替换。

您也可以使用Unicode Utitilies

$ uniname f.txt 
character  byte       UTF-32   encoded as     glyph   name
        0          0  000057   57             W      LATIN CAPITAL LETTER W
        1          1  000456   D1 96          і      CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I
        2          3  00006E   6E             n      LATIN SMALL LETTER N
        3          4  000064   64             d      LATIN SMALL LETTER D
        4          5  00000A   0A                     LINE FEED (LF)
        5          6  00006C   6C             l      LATIN SMALL LETTER L
        6          7  000069   69             i      LATIN SMALL LETTER I
        7          8  00006B   6B             k      LATIN SMALL LETTER K
        8          9  000065   65             e      LATIN SMALL LETTER E
        9         10  00000A   0A                     LINE FEED (LF)

在您发现文件中的哪些符号不是ASCII后,您可以将它们替换为等效的ASCII文件。

$ sed -i 's/\xd1\x96/i/g' f.txt