在 Linux 上,我有一个包含大量文件的目录。其中一些具有非 ASCII 字符,但它们都是有效的 UTF-8。一个程序有一个错误,阻止它使用非 ASCII 文件名,我必须找出有多少受到影响。我打算用 find
执行此操作,然后执行 grep 来打印非 ASCII 字符,然后执行 wc -l
来查找数字。它不必是 grep;我可以使用任何标准的 Unix regular expression,例如 Perl、sed、AWK 等。
但是,是否有“任何不是 ASCII 字符的字符”的正则表达式?
/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F-\x9F]
不,[^\x20-\x7E]
不是 ASCII。
这是真正的 ASCII:
[^\x00-\x7F]
否则,它将删除作为 ASCII 表一部分的换行符和其他特殊字符!
您还可以查看此页面:Unicode Regular Expressions,因为它包含一些有用的 Unicode 字符类,例如:
\p{Control}: an ASCII 0x00..0x1F or Latin-1 0x80..0x9F control character.
您可以使用此正则表达式:
[^\w \xC0-\xFF]
案例询问,选项是多行。
[^\x00-\x7F]
和 [^[:ascii:]]
缺少一些控制字节,因此 strings 有时可能是更好的选择。例如,cat test.torrent | perl -pe 's/[^[:ascii:]]+/\n/g'
会对您的终端做一些奇怪的事情,而 strings test.torrent
的行为则相同。
验证文本框接受 Ascii 仅使用此模式
[\x00-\x7F]+
我使用 [^\t\r\n\x20-\x7E]+
,这似乎工作正常。
你真的不需要正则表达式。
printf "%s\n" *[!\ -~]*
这也将显示名称中带有控制字符的文件名,但我认为这是一个功能。
如果您没有任何匹配的文件,除非您设置了 nullglob
,否则 glob 将扩展为自身。 (表达式本身不匹配,所以从技术上讲,这个输出是明确的。)
shopt -s nullglob dotglob globasciiranges
跳过不匹配的模式,包括像 .tmp§
这样的点文件名,而不是依赖于当前的语言环境。我的意思是只为这个特定的命令临时设置它,否则默认设置就可以了。
结果证明这是非常灵活和可扩展的。 $field =~ s/[^\x00-\x7F]//g ; # 因此所有有问题的非 ASCII 或特定项目都可以被清除。在选择或预处理最终将成为哈希键的项目方面非常好。
不定期副业成功案例分享
^
在 PCRE 中有效。:print:
不能在 UTF8 终端中工作?这在 UTF8 终端中对我有用:27.chr =~ /[^[:print:]]/
rename 's/[^\x00-\x7F]//g' *
(您可以先使用-n
检查重命名是否正常)。