[英]Searching for non-ascii characters
我有一个文件,a.out,其中包含许多行。 每行只有一个字符,可以是unicode字符U+2013
或小写字母az
。
在a.out上执行文件命令会引发结果UTF-8 Unicode文本。
locale命令报告:
LANG=en_US.UTF-8
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=
如果我发出命令grep -P -n "[^\\x00-\\xFF]" a.out
我希望只返回包含U+2013
的行。 如果我在cygwin下进行测试就是这种情况。 然而,问题环境是Oracle Linux Server 6.5版,问题是grep命令不返回任何行。 如果我发出grep -P -n "[\\x00-\\xFF]
”a.out,则返回所有行。
我意识到“ [grep -P]
......是高度实验性的, grep -P
可能会警告未实现的功能。” 但没有发出警告。
我错过了什么吗?
我建议避免使用狡猾的grep -P
实现并使用真实的东西。 这有效:
perl -CSD -nle 'print "$.: $_" if /\P{ASCII}/' utfile1 utfile2 utfile3 ...
哪里:
-CSD
选项表示stdio trio(stdin,stdout,stderr)和磁盘文件都应该被视为UTF-8编码。
$.
代表当前记录(行)编号。
$_
代表当前行。
\\P{ASCII}
匹配任何非 ASCII的代码点。
我如何grep中的注释对于UNIX中的所有非ASCII字符给出了答案:
Grep(和系列)不进行Unicode处理,将多字节字符合并到单个实体中,以便进行正则表达式匹配。
这意味着,UTF-8编码U+2013
( 0xe2
, 0x80
, 0x93
)不是通过作为grep的给定范围之外的单个打印字符的部分进行处理。
GNU grep手册对-P
没有提到Unicode或UTF-8。 相反,它说将模式解释为Perl正则表达式。 (这并不意味着结果与 Perl 相同 ,只是一些反斜杠转义类似 )。
可以告诉 Perl本身使用UTF-8编码。 但是,在过滤无效的utf8中使用Perl的示例不使用该功能。 相反,表达式(如有问题的grep中的表达式)仅测试单个字节 - 而不是完整字符。
gawk可以帮助你解决这个问题,
这是awk单行:
awk -v FS="" 'BEGIN{for(i=1;i<128;i++)ord[sprintf("%c",i)]=i}
{for(i=1;i<=NF;i++)if(!($i in ord))print $i}' file
以下是gawk的测试:
kent$ cat f
abcd
+ß
s+äö
ö--我
中文
kent$ awk -v FS="" 'BEGIN{for(i=1;i<128;i++)ord[sprintf("%c",i)]=i}{for(i=1;i<=NF;i++)if(!($i in ord))print $i}' f
ß
ä
ö
ö
我
中
文
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.