如何使用find获取所有没有.git文件夹的文件夹?
在这个结构上::
$ tree -a -d -L 2
.
├── a
│ └── .git
├── b
│ ├── b1
│ └── b2
├── c
└── d
└── .git
├── lkdj
└── qsdqdf
此::
$ find . -name ".git" -prune -o -type d -print
.
./a
./b
./b/b1
./b/b2
./c
./d
$
获取除.git
以外的所有文件夹我想得到这个::
$ find . ...
.
./b
./b/b1
./b/b2
./c
$
答案 0 :(得分:3)
效率低下(运行一堆子进程),但以下将使用GNU或现代BSD find
完成工作:
find . -type d -exec test -d '{}/.git' ';' -prune -o -type d -print
如果您不能保证find
具有POSIX标准中无法保证的任何功能,那么您可能需要进一步降低效率(使{}
通过让shell运行测试来拥有自己的令牌而不是子串:
find . -type d -exec sh -c 'test -d "$1/.git"' _ '{}' ';' -prune -o -type d -print
这可以使用-exec
作为谓词,运行find
不支持内置的测试。
请注意使用效率低下的-exec [...] {} [...] \;
而不是效率更高的-exec [...] {} +
;因为后者将多个文件名传递给每个调用,所以它无法获取单个每个文件名的结果,因此总是评估为真。
答案 1 :(得分:1)
如果您不介意使用临时文件,那么:
find . -type d -print > all_dirs
fgrep -vxf <(grep '/\.git$' all_dirs | sed 's#/\.git$##') all_dirs | grep -vE '/\.git$|/\.git/'
rm all_dirs
-x
选项是必需的,因为我们只需要消除完全匹配的行。与Charles' answer相比,它会更有效,因为它不会运行如此多的子进程。但是,如果任何目录中包含换行符,则会产生错误的输出。