GNU 查找包括父目录

GNU 查找包括父目录

我正在尝试让 GNU 找到直到指定文件名的排除条目。

以此树为例:

./foo
./foo/another.txt
./foo/bar
./foo/bar/world
./foo/bar/world/test.txt
./foo/bar/world/hello.txt

(和其他目录中还会有一堆其他文件world,这就是为什么我不只是搜索hello.txt)。

我想要匹配除“test.txt”及其父目录之外的所有内容。

输出应该只是foo/bar/world/hello.txt

此命令产生了正确的结果,但它非常混乱,并且如果存在多个同名目录,则会产生错误的结果:

find * ! -name test.txt -a ! -name foo -a ! -name bar -a ! -name world

答案1

告诉find你你只对文件感兴趣,而不是目录。

find ./foo -type f ! -name test.txt

更新:

假设我们有这个稍微复杂一点的例子:

$ find ./foo
./foo
./foo/baz
./foo/baz/b.csv
./foo/baz/a.txt
./foo/bar
./foo/bar/c.txt
./foo/bar/world
./foo/bar/world/hello.txt
./foo/bar/world/test.txt

如果您的目标是删除某些内容,则需要指定-depth文件在其目录之前显示:

$ find ./foo -depth
./foo/baz/b.csv
./foo/baz/a.txt
./foo/baz
./foo/bar/c.txt
./foo/bar/world/hello.txt
./foo/bar/world/test.txt
./foo/bar/world
./foo/bar
./foo

如果您知道要保留的路径,我们可以设计一个与其部分匹配的正则表达式:

$ find ./foo -depth -regextype posix-extended -regex '^\./foo(/bar(/world(/test.txt)?)?)?'
./foo/bar/world/test.txt
./foo/bar/world
./foo/bar
./foo

然后我们可以否定正则表达式来获得想要删除的内容:

$ find ./foo -depth -regextype posix-extended ! -regex '^\./foo(/bar(/world(/test.txt)?)?)?'
./foo/baz/b.csv
./foo/baz/a.txt
./foo/baz
./foo/bar/c.txt
./foo/bar/world/hello.txt

答案2

如果您知道树的确切深度(即您想要从第三个文件夹开始获取文件),您可以使用:

find . -mindepth $depth ! -name test.txt

通过您的目录结构,我得到:

$ find . -mindepth 4 ! -name test.txt
./foo/bar/world/hello.txt

这正是您所期望的。


编辑:这应该更好(但更丑!)。它找到所在test.txt的目录并找到其中的所有文件。优点是它完全独立于父路径,它会自动计算它们。

EXCLUDEFNAME="test.txt"; find $(find . -name "$EXCLUDEFNAME" -exec dirname {} \; -quit) -mindepth 1 ! -name "$EXCLUDEFNAME"

多行更好:

EXCLUDEFNAME="test.txt"
targetpath="$(find . -name "$EXCLUDEFNAME" -exec dirname {} \;)"
find "$targetpath" -mindepth 1 ! -name "$EXCLUDEFNAME"

相关内容