使用grep匹配具有固定数量字符的字符串


9

我正在尝试使用查找所有6字母词grep。我目前有这个:

grep "^.\{6\}$" myfile.txt 

但是,我发现我也得到了如下结果:étuisétude

我怀疑这与e以上文字中的符号有关。

我有什么办法可以确保不会发生这种情况?

谢谢你的帮助!

Answers:


4

grep角色的观念是与地区有关的。如果您位于非Unicode语言环境中,并且从其中包含Unicode字符的文件进行grep操作,则字符计数将不匹配。如果echo $LANG这样,您将看到您所在的语言环境。

如果将LC_CTYPEand和/或LANG环境变量设置为以“ .UTF-8”结尾的值,则将获得正确的行为:

$ cat data
étuis
letter
éééééé
$ LANG=C grep -E '^.{6}$' data
étuis
letter
$ LANG=en_US.UTF_8 grep -E '^.{6}$' data
letter
éééééé
$

通过在与命令相同的行上分配变量,可以仅更改单个命令的语言环境。

使用此配置,多字节字符被视为单个字符。如果要完全排除非ASCII字符,则其他一些答案也可为您提供解决方案。


请注意,在存在组合字符的情况下,事情仍然有可能破裂,或者至少不能完全按照您的预期进行。您grep可能对拉丁文小写字母E +合并字符急性的处理方式与拉丁文小写字母E与急性处理方式不同。


如果您使用.,则类似内容wăsd's将匹配
cuonglm

'是一个字符,可以合理地成为“具有固定数量字符的字符串”的一部分。
Michael Homer 2014年

也许。并且您应该同时设置LC_CTYPELANG,类似的操作LC_CTYPE=en_US.UTF-8 LANG=en_US将会失败。使用LC_ALL安全。
cuonglm

2

尝试这个:

LC_ALL=C.UTF-8 grep -x '[_[:alnum:]]\{6\}' file

-x用于匹配整行,并由POSIX定义(请参见grep)。

请参见此处,以了解有关功能的详细说明LC_ALL。您可以设置LANGLC_CTYPE使用utf-8来获得相同的行为。影响顺序为LC_ALL=> LANG=> LC_CTYPE


2

随着GNU grep当PCRE支持,那么你可以这样做:

grep -Px '\X{6}'

虽然.比赛的字符,\X匹配表意文字/ graphem。

在UTF-8语言环境中:

$ locale charmap
UTF-8
$ printf '\u00e9tuis\n\u00e9tudes\n' | grep -Px '\X{6}'
études
$ printf 'e\u0301tuis\ne\u0301tudes\n' | grep -Px '\X{6}'
études

在后者中études,有7个字符,8个字节和6个字素。


似乎不起作用:echo épée | grep -Px '\X{6}'输出épée
cuonglm,2014年

@Gnouc,您需要在UTF-8语言环境中运行它(如果é以上内容是使用UTF-8编码的)。
斯特凡Chazelas

哦,我的错误。它与UTF-8一起使用。
cuonglm

0

您可以尝试类似:

grep "^[A-Za-z]\{6\}$" myfile.txt

或者如果单词也可能包含数字,则:

grep "^[A-Za-z0-9]\{6\}$" myfile.txt

除了这些字符外,只需将任何其他字符添加到所需的方括号中即可。


这根本不会与匹配étude,因为与重音对应的ASCII字符会弄乱正则表达式。
亚历克斯(Alex)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.