.gitを含まない現在のディレクトリのすべてのサブディレクトリを印刷します。

.gitを含まない現在のディレクトリのすべてのサブディレクトリを印刷します。

現在のフォルダのすべてのサブディレクトリを見て、「.git」を含まないサブディレクトリがあるかどうかを知らせるbash行を作成しようとしています。偽:

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

これは私が試しているコードの1行です。動作せずにすべてのサブディレクトリを印刷するようです。

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。これはユーザーのログインシェルで、スクリプトなどに使用するための特別な意味はありません。自分で使用するか、選択したシェルのsh場合に使用bashしてください。ksh

これはうまくいくかもしれません:

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

ムルの答えあなたのアプローチにどのような問題があるか説明してください。答えあなたが言った問題はシェルを含まないより簡単なアプローチを提案します。

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これにより、所望の結果を得るために使用されるテスト実行が無効になります。

関連情報