如何使用不同的字符集获取uniq字符串

时间:2018-02-16 11:38:15

标签: linux bash awk character-encoding

我有一个文件1.txt

$ cat 1.txt 
page1
рage1

可是:

$ head -n1 1.txt | file -i -
/dev/stdin: text/plain; charset=us-ascii

$ head -n2 1.txt | tail -n1 | file -i -
/dev/stdin: text/plain; charset=utf-8

字符串有不同的字符集。因为它我不能用我知道的方法得到唯一的字符串:

$ cat 1.txt | sort | uniq -c | sort -rn
      1 рage1
      1 page1

那么,你能帮助我找到在我的情况下如何获得唯一字符串的方法吗? 附:首选解决方案只能使用linux命令行/ bash / awk。 但是如果你有另一种编程语言的解决方案,我也会喜欢它。

UPD。 awk '!a[$0]++' Input_file不起作用,pic:

enter image description here

1 个答案:

答案 0 :(得分:1)

粗略检查我们在这里所拥有的东西:

$ cat 1.txt
page1
рage1
$ hd 1.txt
00000000  70 61 67 65 31 0a d1 80  61 67 65 31 0a           |page1...age1.|
0000000d

正如对该问题的评论所述,第二个“рage1”确实与之前的“page1”不同,原因是:那不是拉丁文p,它是一个西里尔文р,所以除非您事先规范化文本,否则唯一性过滤器应将它们分开调用。

iconv不会在这里耍手段。 uconv(例如,Debian / Ubuntu上的apt install icu-devtools)会让你接近,但它的transliteration mappings基于语音而不是相似的字符,所以当我们音译这个例子时,西里尔文{{1}成为拉丁语р

r

另见these more complex uconv commands,其结果相似。

ICU uconv man page

  

uconv 还可以对转码后的数据运行指定的音译,在这种情况下,在将数据转码为Unicode后,音译将作为中间步骤发生。 音译可以是以分号分隔的音译器名称列表,也可以是ICU音译规则格式中任意复杂的规则集。

这意味着有人可以使用“ICU音译规则格式”来指定相似的字符映射。当然,按照这个速度,你可以使用你想要的任何语言。

我也试过perl的Text::Unidecode,但它有自己的(类似的)问题:

$ uconv -x Cyrillic-Latin 1.txt
page1
rage1

在某些情况下,这可能会更好,但显然这不是其中之一。