打印当前目录中不包含.git的所有子目录

打印当前目录中不包含.git的所有子目录

我正在尝试编写一个 bash 行,它将查看当前文件夹中的所有子目录,并告诉我是否有不包含“.git”的子目录。伪:

for subdir in currentdir
  if .git does not exist
    print subdir

这是我正在尝试的单行代码,它不起作用并且似乎打印了所有子目录:

find . -maxdepth 1 -type d -execdir $SHELL -c '[ ! -d ".git" ] && echo "not git repo:" {}' $SHELL -c '{}' ';'

我找到了一些解决方案,可以让我打印所有具有 .git 的子目录,例如这个——我正在尝试做相反的事情。

我究竟做错了什么?这可能吗?

答案1

首先,该-execdir命令看起来很奇怪(2x $SHELL -c?):

$SHELL -c '[ ! -d ".git" ] && echo "not git repo:" {}' $SHELL -c '{}' ';'

此外,-execdir在包含匹配实体的目录(即当前正在检查的目录的父目录)中运行该命令,该目录适用.于所有子目录。测试在错误的目录中运行。和:

  • 您不应该重复使用{}in exec/-execdir命令。
  • 没有理由使用$SHELL.这是用户的登录 shell,对于在脚本等中使用没有任何特殊意义。只需直接使用sh, 或者bash或者ksh如果这些是您选择的 shell。

这可能有效:

find . -maxdepth 1 -type d -exec sh -c '! [ -d "$1/.git" ] && echo "not git repo: $1"' _ {} \;

-exec命令检查传入的参数中是否存在.git,依次是每个子目录。您可能还想使用-mindepth 1排除当前目录:

find . -maxdepth 1 -mindepth 1 -type d -exec sh -c '! [ -d "$1/.git" ] && echo "not git repo: $1"' _ {} \;

或者,仅使用 bash,即可dotglob匹配隐藏目录:

(shopt -s dotglob; for d in ./*/; do [[ -d $d/.git ]] || echo "not git repo: $d"; done)

答案2

穆鲁的回答解释你的方法有什么问题。的答案你提到的问题建议一种不涉及 shell 的更简单的方法:

find . -maxdepth 1 -type d -exec test '!' -e '{}/.git' ';' -printf "not git repo: %p\n"

(假设你的find支持-printf),或者

find . -maxdepth 1 -type d -exec test '!' -e '{}/.git' ';' -print

-exec test这会否定用于获得所需结果的测试运行。

相关内容