【问题标题】:Confusion about the text file encoding and how to transform between different encoding method?关于文本文件编码的困惑以及如何在不同的编码方法之间进行转换?
【发布时间】:2017-03-31 22:17:11
【问题描述】:

我有一个文本文件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$  

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

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

我的目标是将此文件转换为该文件中的所有单词都可以通过grepsed 找到的格式...仅此而已。

【问题讨论】:

  • 确保这两种格式都在iconv -l中列出
  • @Arash 我用iconv -l 测试过,UTF-8 和 US-ASCII 都在列表中。你能把这两个词复制到这里吗:Wіnd,like,看看你有没有同样的问题?
  • 这对我来说很好:printf "Word\nlike\n" | iconv -f UTF-8 -t US-ASCII

标签: linux encoding sed utf-8 ascii


【解决方案1】:

UTF-8 是 Unicode 字符集的编码。一些 Unicode 字符位于相似的子集中,有时统称为“可混淆字符”。所以,

f.txt | grep "Wind"

将寻找LATIN SMALL LETTER I,而

f.txt | grep "Wіnd"

将寻找CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I。你可以写成

f.txt | grep "W\xD1\x96nd"

由于 і 不是 ASCII 字符集的成员,它不能以 ASCII 编码。

如果您想更进一步,我建议您不要放弃 UTF-8 作为您的文本文件编码,但您可能希望将易混淆的字母音译为 Basic Latin 或使用处理音译的搜索库作为特征。 grep 正好满足您的要求。

【讨论】:

    【解决方案2】:

    在我的示例中,我将在单词“Wind”中使用“i”,即十六进制 CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN Id196

    要找出符号十六进制表示,您可以使用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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-29
      • 1970-01-01
      • 2011-08-26
      相关资源
      最近更新 更多