特定のファイルを含む除外パスを探す

特定のファイルを含む除外パスを探す

.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

これは3つのワークセットに適用されます。

  • -exec [ -f {}/.git ] \; -prune次の名前のファイルを含むディレクトリのクリーンアップ.git
  • -name .git -prune指定されたディレクトリをクリーンアップします.git(したがって、コマンドは.gitリポジトリのホームディレクトリ内で検索されません)。
  • -print上記で取り込まれていない内容を印刷します。

ディレクトリのみを一致させるには、-type dbefore-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 1findが私たちが始めたフォルダを見つけることができないようにオプションが必要です。これにより、無限ループが生成されます。
  • -prunefindがディレクトリに降りるのを防ぐ必要があります。私たちは内部で直接やります-exec
  • -exec "$0" {}$0見つかった内容と同じスクリプトが呼び出されます。

答え3

.gitまたは.hgリポジトリの内部を見ないようにfindを指示する方法は次のとおりです。

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:

はい、それは間違っています。すみません。編集しましたが、実際に動作します。

関連情報