如何在目录中递归地找到所有扩展名为大写的文件。
我试过了 :
$ find -name "*.[A-Z][A-Z][A-Z]"
似乎有效,但当然这不会检查最后一个点后有超过 3 个字母的文件。
答案1
以下适用于简单情况:
find -name "*.*[A-Z]*" ! -name "*.*[^A-Z]*"
如果文件名称中有两个或多个点,则可能会失败。在这种情况下,您需要使用正则表达式,例如grep
:
find | grep '\.[A-Z][A-Z]*$'
或者egrep
:
find | egrep '\.[A-Z]+$'
[:upper:]
根据 Kamil Maciorowski 的评论,可以通过使用代替 来使答案与语言环境无关A-Z
,如下所示:
find | egrep '\.[[:upper:]]+$'
我担心我们这些以英语为母语的人很容易忘记这些事情。
答案2
您可以使用带有 -regex 选项的 RE
find -regextype posix-egrep -regex '.*\.[A-Z]{3}'
使用 RE 和 find 时有一些要点,这是我在 pt_BR 书中学到的。
-regex
选项想要匹配整个路径,因此.*
会匹配您想要匹配的实际 RE 之前的所有内容。如果 RE 可以位于中间,则.*
必须将另一个放置在末尾。
告诉-regextype
哪些元字符必须转义或不转义。
我所知道的是,在 Unix/BSD 中find -E
允许所有元字符不转义,在 GNU/Linux 中也是如此-regextype posix-extended
,
-regextype posix-awk
或-regextype posix-egrep
。
答案3
我最近遇到了类似的问题 - 搜索具有扩展名中至少有一个大写字符我对这个问题的纯 Bash 解决方案是:
#!/bin/bash
# find files with at least one uppercase character in an extension
shopt -s nullglob dotglob globstar
for file in ./**/*; do
if [[ -f $file ]]; then
file_basename=$(basename "$file")
ext="${file_basename#*.}"
[[ $ext =~ [[:upper:]] ]] && echo "$file"
fi
done