![grep 或 sed 无法识别某些 UTF-8 字符](https://linux22.com/image/33954/grep%20%E6%88%96%20sed%20%E6%97%A0%E6%B3%95%E8%AF%86%E5%88%AB%E6%9F%90%E4%BA%9B%20UTF-8%20%E5%AD%97%E7%AC%A6.png)
尝试确定文件中的所有字符。
该文件sample
包括:
a eɪ
abandon əˈbændən
ability əˈbɪləti
able ˈeɪbəl
able ˈeɪbl
abortion əˈbɔrʃən
abortion əˈbɔrʃn
about əˈbaʊt
above əˈbʌv
abroad əˈbrɔd
确认区域设置正确:
$ echo $LANG
en_US.UTF-8
获取第二个字段的命令,按字符分割,然后计算有多少个:
$ cat sample | awk '{print $2}' | grep -o . | sort | uniq -c | sort -n
1 a
1 æ
1 i
1 v
2 d
2 t
3 e
3 l
3 ɔ
3 r
4 n
9 b
11 ə
17 ɪ
ʃ
和在哪里ˈ
?他们没有组合字符或任何特殊的东西。请注意,其他 UTF-8 字符将被拉出:例如ɔ
、ə
和。ɪ
BTW using 的sed 's/\(.\)/\1\n/g'
结果几乎与 相同grep -o .
,只是它添加了一行“\n”。
我有什么遗漏的吗? grep 有隐藏的 UTF-8 选项吗?
如果重要的话我正在使用Ubuntu 12.04.2 LTS
.
答案1
问题在于sort
和uniq
正在使用区域设置的排序规则信息。关闭两个命令的区域设置是有效的:
cat sample | awk '{print $2}' | grep -o . | LC_ALL=C sort | LC_ALL=C uniq -c | sort -n
1 ʊ
1 ʌ
1 a
1 æ
1 i
1 v
2 ʃ
2 d
2 t
3 e
3 l
3 ɔ
3 r
4 ɪ
4 n
9 ˈ
9 b
11 ə
答案2
但是,通过使用“C”语言环境,您会失去人工整理(例如使“a”和“A”等效)。
如果您需要整理和处理 glibc 语言环境数据未处理的某些字符;您可以通过扩展默认排序规则来创建自己的区域设置。
您可以将当前语言环境的定义(例如 /usr/share/i18n/locales/en_US )复制到另一个名称。然后编辑它,在 LC_COLLATE 部分有:
LC_COLLATE
copy "iso14651_t1"
reorder-after <e>
<U0259> <e>;<PCL>;<MIN>;IGNORE
reorder-after <s>
<U0283> <s>;<PCL>;<MIN>;IGNORE
reorder-end
END LC_COLLATE
编译它:localedef -f ./yourmodifiedfile -t UTF-8 ./someplace
然后你可以使用LC_ALL=./someplace
而不是LC_ALL=C
如果您想定期使用它,请将创建的目录与其他标准区域设置(通常是 /usr/share/locale 或 /usr/lib/locale )放在一起,并以标准方式命名(例如,如果它基于 en_US 您例如,可以将其命名为“en_US@IPA”,然后您可以将语言环境设置为永久 LC_COLLATE=en_US@IPA(请注意,如果您想单独定义某些 LC_* 变量,则不得定义 LC_ALL)。
另请注意,U+02C8 是一个修饰符,因此在排序规则中应正确地被忽略。但如果您需要将其作为单独的字符处理,则可以使用它(ascii 单引号与 U+02C8 相同(用于整理视图),因为这就是它经常键入的方式):
# defines a handy symbol, to group together similar chars
collating-symbol <'>
# define
reorder-after <z>
<'>
reorder-after <e>
<U0259> <e>;<PCL>;<MIN>;IGNORE
reorder-after <s>
<U0283> <s>;<PCL>;<MIN>;IGNORE
reorder-after <'>
<U0027> <'>;<BAS>;IGNORE;IGNORE
<U02C8> <'>;<PCL>;IGNORE;IGNORE
reorder-end
行是:<unicode value> <1st level>;<2d level>;<3d level>;<4th level>
级别是用于对它们进行排序的级别。
我认为(但没有尝试过,我把它作为一个练习:))如果你只定义最后一个级别,它将在排序时表现得大部分被忽略,但从 uniq 的角度来看仍然“不同”(只要链我认为所有级别都是独一无二的,角色也是独一无二的)。
通常第一级是分组符号,就像所有类似 e 的字母一样。第二级通常用于基本字符,还有其他几个符号用于各种重音版本,并且(特殊?)用于“特殊”。 3d 级别通常用于区分大写和小写之类的东西。