2017-07-30 7 views
2

findを使用して.gitフォルダを持たないすべてのフォルダを取得する方法?この構造では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

"純粋に"行う方法はないと思いますが、以下の答えは正確です。 – linuxfan

+0

改行で区切られたファイルのリストは必ずしも安全ではないことに注意してください。あなたの '' find''の正確なバージョンに応じて 'mkdir -p ./$ '\ n'/etc/passwd'その '-print'の実装では、あなたの出力リストに'/etc/passwd'を得ることができます。 POSIX準拠の 'find -exec'は' find'の正確な名前(リテラル改行、制御シーケンスなど)を得るためにも使えますが、このようなあいまいさはfind-print0の動機の大部分です。 –

答えて

3

これは非効率的です(サブプロセス)が、以下はGNUや近代的なBSD findで仕事をする:あなたは、POSIX標準で保証されていない任意の機能をfindを持つことが保証していない場合

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

、あなたが取る必要があるかもしれませんより一層効率損失(シェルテストを実行有することによって、むしろサブより、{}独自のトークンを作るため)の:

find . -type d -exec sh -c 'test -d "$1/.git"' _ '{}' ';' -prune -o -type d -print 

これは述語として-execを使用して動作し、runniテストでは、findはビルトインをサポートしていません。

より効率的なではなく、非効率な-exec [...] {} [...] \;の使用に注意してください。後者が各呼び出しに複数のファイル名を渡すので、個々のファイル名ごとの結果を返す方法がないため、常にtrueと評価されます。

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と比べると、これほど多くのサブプロセスが実行されないという点で、これは少し効率的です。しかし、いずれかのディレクトリに改行文字が含まれていると、出力が間違ってしまう。

+1

それがより効率的であるかどうかは、 '.git'兄弟がどれくらいの深さにあるか(そしてそれらがなくてもどれくらいのディレクトリがあるかに依存します)。 '-prune'が欠けていると、' find'に再帰するように指示していることを意味します。 –

関連する問題