使用find获取没有.git子文件夹的所有文件夹

时间:2017-07-30 16:47:14

标签: bash gnu-findutils

如何使用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
$

2 个答案:

答案 0 :(得分:3)

效率低下(运行一堆子进程),但以下将使用GNU或现代BSD find完成工作:

find . -type d -exec test -d '{}/.git' ';' -prune -o -type d -print

如果您不能保证find具有POSIX标准中无法保证的任何功能,那么您可能需要进一步降低效率(使{}通过让she​​ll运行测试来拥有自己的令牌而不是子串:

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
  • 第一步将所有子目录路径转换为all_dirs文件
  • 第二步过滤掉具有.git子目录的目录以及.git子目录。 -x选项是必需的,因为我们只需要消除完全匹配的行。

Charles' answer相比,它会更有效,因为它不会运行如此多的子进程。但是,如果任何目录中包含换行符,则会产生错误的输出。