我想在目录树中查找包含扩展 ASCII 字符 (0x80-0xFF) 的所有文件名。我想我可以这样做:
find . -regex '.*[\x80-\xFF]+.*'
但它却匹配一切。另外,我尝试查找包含不在标准 az、AZ、0-9、连字符或句点集中的任何字符的文件。
find . -regex '.*[^- a-zA-Z0-9]+.*'
显然我在这里误解了一个基本方面。
我的树中的文件示例:
./file 1/file - 1 - A2.mkv
./file 1/file - 1 - A2.nfo
./tést/tést - 2 - 2.mkv
./français/français - 2 -3.mkv
我在 Ubuntu 20.04 下使用 find (GNU findutils) 4.7.0。
答案1
$ tree
.
|-- file 1
| |-- file - 1 - A2.mkv
| `-- file - 1 - A2.nfo
|-- français
| `-- français - 2 -3.mkv
`-- tést
`-- tést - 2 - 2.mkv
3 directories, 4 files
$ LC_ALL=C find . -name '*[![:print:]]*'
./tést
./tést/tést - 2 - 2.mkv
./français
./français/français - 2 -3.mkv
这会将命令的区域设置设置find
为标准 POSIX 区域设置。字符print
类包含属于字符类alpha
、digit
、的字符punct
,并且还包括空格字符。这意味着测试-name '*[![:print:]]*'
将是真的对于任何包含以下字符的文件名不是在print
课堂里。
如果您不想查找具有各种其他空格字符(制表符等)的名称,请用作[![:graph:][:space:]]
测试(print
和之间的唯一区别graph
是graph
不包含空格字符)。
答案2
Kusalananda 的答案还包括带有 ASCII 控制字符的文件名。这可能是可取的,但如果不是,这里有一个基于 Kusalananda 的解决方案,它更准确地回答了这个问题:
LC_ALL=C find . -name $'*[\x80-\xff]*'
使用示例:
$ touch foo bár $'baz\x01'
$ ls
bár 'baz'$'\001' foo
$ LC_ALL=C find . -name $'*[\x80-\xff]*'
./b??r
$ LC_ALL=C find . -name $'*[\x80-\xff]*' | od -tx1z
0000000 2e 2f 62 c3 a1 72 0a >./b..r.<
0000007
与您尝试的不同之处在于,在这里,shell 是解释十六进制转义序列而不是将其留给find
.另外,LC_ALL=C
可能是需要的,因为否则.
在正则表达式或*
全局变量中会将这些字节匹配为其他字符的一部分。