如果某些父目录包含某些子目录名称模式,我该如何从 find 输出中排除它?我有类似的目录树:

fnd
|-- aaa
|   `-- 2023.11.12
|-- bbb
|   |-- 2023.12.12
|   `-- 2024.03.03
`-- ccc

当我运行命令时:

find fnd/* -type d -not -name "2024*" -maxdepth 1 -mindepth 1 -prune

它给了我:

fnd/aaa/2023.11.12
fnd/bbb/2023.12.12

但我只需要不包含子目录的目录。那么我如何才能只看到

fnd/aaa/2023.11.12


最佳答案
1

如果您只是想要那个特定的目录名称,那么以下内容就可以起作用:

find fnd/* -mindepth 1 -maxdepth 1 -type d -exec test ! -d "{}/2024.03.03" \; -print

输出:

fnd/aaa/2023.11.12

它使用test命令检查返回的目录中是否find有没有子目录2024.03.03,并打印没有的子目录。只返回了两个目录,只有一个目录没有同名的子目录,因此将其打印出来。

您想要的是打印名称不以模式(或字符串)开头的目录,2024而不管后面包含什么。上面的代码无法通过添加通配符来实现,*因为test只查找确切的目录名称,并且不会扩展通配符,因此下面的代码将返回两个目录,因为它们都不包含名为的子目录2024*。这就是您不想要的,如下所示:

find fnd/* -mindepth 1 -maxdepth 1 -type d -exec test ! -d "{}/2024*" \; -print

输出:

fnd/aaa/2023.11.12
fnd/bbb/2023.12.12

看起来好像可以添加if [ ! -d {}/2024* ]; then echo {}; fi \;-exec开关中,find但这样做不起作用,因为if它是一个 shell 关键字,-exec只能执行命令和脚本。

获得所需内容的最简单方法是创建一个包含以下内容的脚本:

#!/bin/bash

if [ ! -d $1/2024* ]; then echo $1; fi

然后使用以下命令:

find fnd/* -mindepth 1 -maxdepth 1 -type d -exec ./script {} \;

输出:

fnd/aaa/2023.11.12

它的作用是执行./script并使用 find 的输出作为{}第一个也是唯一的参数,然后使用if..then语句查看目录是否不以字符串开头2024,并打印不以字符串开头的目录,从而提供预期的输出。

为了验证它是否正常工作,请在其中创建一个fnd/aaa/2023.11.12名为的目录2024.04.04,然后运行find我指定的命令,它将不会输出任何内容,因为两个目录都包含以字符串开头的子目录2024

最后,为了澄清一个细节,您在问题中说您不希望它包含模式,2024但我提到它是not beginning with the pattern 2024因为这是您的通配符所做的,因为您将其设置为2024*。要使其2024完全不包含您所说的字符串,请使用*2024*

#!/bin/bash

if [ ! -d $1/*2024* ]; then echo $1; fi