查找包含特定文件的排除路径

查找包含特定文件的排除路径

我试图递归地查找文件夹中的所有目录,同时通过排除所有包含.git文件的路径来排除所有 git 子模块。我怎样才能做到呢?


解释:

.git文件存在于每个子模块文件夹的根目录中。该子模块文件夹可以包含在任何地方。


测试用例

$ mkdir Test
$ cd Test
$ mkdir a
$ mkdir b
$ mkdir c
$ cd a
$ mkdir .git
$ cd ..
$ cd b
$ touch .git
$ cd ..
$ cd c
$ mkdir c1
$ mkdir c2
$ cd..
$ find . -type d \( \( ! -name . -exec [ -e {}/.git ] \; -prune \) -o \( \( \
 -name .git\
 -o -name .vscode\
 -o -name node_modules\
 -o -name Image\
 -o -name Rendered\
 -o -name iNotebook\
 -o -name GeneratedTest\
 -o -name GeneratedOutput\
  \) -prune \) -o -print \) | sort 

预期成绩

.
./a
./c
./c/c1
./c/c2

答案1

find操作也是测试,因此您可以使用以下命令添加测试-exec

find . \( -exec [ -f {}/.git ] \; -prune \) -o \( -name .git -prune \) -o -print

这适用于三组操作:

  • -exec [ -f {}/.git ] \; -prune修剪包含名为的文件的目录.git
  • -name .git -prune修剪指定的目录.git(因此该命令不会在.git存储库的主目录内搜索)
  • -print打印上面未捕获的任何内容。

要仅匹配目录,请-type d在 之前添加-print,或者(以节省处理文件的时间):

find . -type d \( \( -exec [ -f {}/.git ] \; -prune \) -o \( -name .git -prune \) -o -print \)

.通过更改find启动路径,在除 之外的目录上运行此命令时,这也适用:

find /some/other/path -type d \( \( -exec [ -f {}/.git ] \; -prune \) -o \( -name .git -prune \) -o -print \)

答案2

我们可以创建一个递归find

将以下行添加到脚本文件中:

#!/bin/bash
if [ ! -f "$1"/.git ]; then
    echo "$1"
    find "$1" -mindepth 1 -type d -prune -exec "$0" {} \;
fi

我命名了该文件findifnotgit,但这并不重要。然后使其可执行

chmod u+x findifnotgit

然后使用您想要运行的路径作为参数运行它:

./findifnotgit .

-->.对于当前目录

或者

./findifnotgit /path/to/search/

解释:

  • if [ ! -f "$1"/.git ]; then ... fi.git仅当当前文件夹中没有文件时才运行以下命令( $1)
  • 我们需要-mindepth 1选项让 find 找不到我们开始的文件夹,这会创建无限循环。
  • 我们需要-prune让 find 不会下降到目录中。我们会在里面自己做这件事-exec
  • -exec "$0" {}$0将使用发现的内容调用相同的脚本。

答案3

以下是如何告诉 find 不要查看 .git 或 .hg 存储库内部。

find .  \( -iname '.git' -o -iname '.hg' \) -prune -false  -o -iname  '*thing-i-am-looking for*'

答案4

有点脏脚本,但这会找到所有不包含文件的目录.git

#!/bin/bash

# find dirs that contain *.git files and store in array
exclude_dirs=($(find . -type f -iname ".git" | xargs -i dirname {}))

# set up the base command
command="find . -type d"

# loop over each element in array by index
for i in $(seq 0 $(expr ${#exclude_dirs[@]} - 1)); do
    command="${command} -not -path ${exclude_dirs[$i]}"
done

# run the find
eval ${command}

编辑:

修复了语法错误并更新*.git.git

编辑2:

是的,那是错的,我很抱歉。已编辑,现在它实际上可以工作了。

相关内容