(grep)正则表达式以匹配非ASCII字符?


169

在Linux上,我有一个包含大量文件的目录。其中一些具有非ASCII字符,但它们都是有效的UTF-8。一个程序有一个错误,阻止它与非ASCII文件名一起使用,我必须找出有多少受影响。我打算这样做find,然后执行grep打印非ASCII字符,然后执行a wc -l查找数字。不必是grep;我可以使用任何标准的Unix 正则表达式,例如PerlsedAWK等。

但是,是否存在“不是ASCII字符的任何字符”的正则表达式?


1
保罗,是的,我可以使用perl
罗里

/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x9F]
Tinmarino '19

Answers:


310

这将匹配一个非ASCII字符:

[^\x00-\x7F]

这是有效的PCRE(与Perl兼容的正则表达式)。

您还可以使用POSIX速记:

  • [[:ascii:]] -匹配一个ASCII字符
  • [^[:ascii:]] -匹配一个非ASCII字符

[^[:print:]] 可能就足够了。**


3
@adrianm:否,^在PCRE中有效。
Alix Axel

10
没错 但是,您必须使用pcregrep,而不是标准grep。如果您的终端在UTF8中设置,则[^ [:print:]]将不起作用。
罗里

@Rory,为什么:print:不能在UTF8终端中工作?这对我在UTF8终端中的撬动有效:27.chr =~ /[^[:print:]]/
akostadinov 2014年

这对于修复错误的文件名确实非常好- rename 's/[^\x00-\x7F]//g' *(您可以-n先检查重命名是否正确)。
naught101

如何匹配非UTF8的任何字符和其他任何特定的字符?
CMCDragonkai '16

37

不,[^\x20-\x7E]不是ASCII。

这是真正的ASCII:

 [^\x00-\x7F]

否则,它将修剪掉换行符和ASCII表中的其他特殊字符!



3

[^\x00-\x7F][^[:ascii:]]错过了一些控制字节,因此有时字符串可能是更好的选择。例如,cat test.torrent | perl -pe 's/[^[:ascii:]]+/\n/g'它将对您的终端产生奇怪的影响,strings test.torrent并表现正常。




2

您可以使用此正则表达式:

[^\w \xC0-\xFF]

案例询问,选项是Multiline


2

您真的不需要正则表达式。

printf "%s\n" *[!\ -~]*

这也会显示名称中带有控制字符的文件名,但是我认为这是一项功能。

如果没有任何匹配的文件,则除非已nullglob设置,否则该glob会扩展为自身。(该表达式本身不匹配,因此从技术上讲,此输出是明确的。)


迟来的是,如果您确实有一些与此模式匹配的文件,我可以观察到它确实可以正常工作。当没有匹配项时,模式会自行打印的行为有些令人惊讶,但实际上是正确的。我编辑了答案,希望可以澄清这一点。
Tripleee

1

事实证明,这是非常灵活和可扩展的。$ field =〜s / [^ \ x00- \ x7F] // g; #因此可以清除所有非ASCII或相关特定项目。在选择或预处理最终将成为哈希键的项目时非常好。

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.