按长度过滤查找结果

Lea*_*nux 3 linux find

我想找到单个目录中的所有子目录。我需要按名称长度进行过滤。我想出了以下几点:

find ./directory -maxdepth 1 -type d
Run Code Online (Sandbox Code Playgroud)

如何按名称长度过滤结果——例如,仅过滤超过 4 个字符的子目录?

Jef*_*ler 9

您可以使用?通配符五次:

find ./directory -maxdepth 1 -type d -name '?????*'
Run Code Online (Sandbox Code Playgroud)

这要求匹配项的名称中至少包含五个字符。

  • +1对于未来可能想要根据**最大**文件名长度过滤`find`结果的读者,`find ./directory -maxdepth 1 -type d -not -name '??????* '` 将查找名称中包含 4 个或更少字符的目录。 (3认同)
  • @JimL,至少使用GNU“find”,它还会报告包含无法解码为字符的字节的目录名称,无论其长度如何。 (2认同)
  • 谢谢你提供的细节,@StéphaneChazelas。我鼓励您发布一个通用解决方案来解决标题中的问题,而不是所述的问题。即,能够根据最小、最大或实际上的长度范围来过滤查找结果。 (2认同)

Sté*_*las 7

使用shell,可以使用glob 限定符按文件类型(此处为目录zsh过滤 glob ,并且打开该选项后,您将获得类似于 ERE 的 glob 运算符,因此您可以执行以下操作:extendedglob(#cX,Y){X,Y}

\n
set -o extendedglob\nprint -rC1 -- ?(#c5,)(ND/)\n
Run Code Online (Sandbox Code Playgroud)\n

列出print r由一个或多个字符 ( )组成的目录1 C类型文件( glob 限定符) 。/5?

\n

?(#c5,12)将为 5 到 12 个字符,?(#c,5)?(#c0,5)0 到 5 个字符(并不是说您可以获得包含 0 个字符的文件名)。

\n

D如果您想忽略隐藏的限定符,请删除限定符。

\n

对于zshglob,任何无法解码为字符的字节仍被视为 1(并且将通过 进行匹配?)。

\n

对于包括 GNU 在内的某些find实现find,至少在 GNu 系统上(使用 GNU 正则表达式/fnmatch()来自 GNU libc),它们既不匹配也不?匹配 *(也不匹配 regex .),因此:

\n
find . -maxdepth -name \'?????*\' -type d\n
Run Code Online (Sandbox Code Playgroud)\n

或者

\n
find . -maxdepth 1 -regextype posix-extended -regex \'.*/[^/]{5,}\' -type d\n
Run Code Online (Sandbox Code Playgroud)\n

$\'St\\xe9phane\'例如,如果在 UTF-8 语言环境中运行,则无法匹配目录,因为 0xe9 字节 (ISO8859-1 ) 无法解码为字符,并且除了运行之外\xc3\xa9没有其他解决方法,但你可以计算长度字节而不是字符。findLC_ALL=C

\n

与此等效的 BSD 版本-regex是:

\n
find -E . -maxdepth 1 -regex \'.*/[^/]{5,}\'\n
Run Code Online (Sandbox Code Playgroud)\n

或者

\n
find . -maxdepth 1 -regex \'.*/[^/]\\{5,\\}\'\n
Run Code Online (Sandbox Code Playgroud)\n

(默认是基本正则表达式,而对于 GNU 来说find,它是一些旧的 emacs 正则表达式方言)。

\n

请记住,多字节字符支持因变体而异。

\n

如果在 GNU 系统上,另一种方法是输出以findNUL 分隔的文件路径(因为 NUL 是文件路径中唯一找不到的字符)并按gawk名称长度进行过滤:

\n
find . -mindepth 1 -maxdepth 1 -printf \'%P\\0\' |\n  gawk -v RS=\'\\0\' -F/ \'length($NF) > 4\'\n
Run Code Online (Sandbox Code Playgroud)\n

如果存在无法解码为字符的字节,gawk则会发出警告,但与 一样,每个字节都会为长度贡献 1 zsh

\n