ディレクトリとその内容をターゲットにした場合、-nameスイッチはGNU findとしてどのように機能しますか?

ディレクトリとその内容をターゲットにした場合、-nameスイッチはGNU findとしてどのように機能しますか?

アプリケーションソースファイルでいっぱいのフォルダがあり、プロジェクトはバージョン管理にgitを使用しているため、ディレクトリがあります.git

├── composer.json
├── .git
│   ├── branches
│   ├── config
│   ├── info
│   ├── logs
│   ├── objects
│   ├── packed-refs
│   └── refs
├── .gitignore
├── Gruntfile.js
├── less
│   ├── framework
│   ├── index.less
│   └── view_specific.less
├── package.json
[...]

.gitバージョン指定されたファイル、つまりディレクトリとその下のすべてのエントリを無視しながら、すべてのソースファイルに対して特定のタスクを実行する必要があることがよくあります。
私は通常、次の-not -pathオプションを使用してディレクトリを除外します。find

find . -not -path "*git*" 

.gitignore問題は広すぎるということです。たとえば、そのファイルとそのファイルを含む他のファイルを除外します。その中では、例えば揺れ逃亡者
find-nameスイッチがディレクトリとその内容をターゲットにして-pruneいるようです。.git

% find . -name ".git" -prune -o -print | grep git
./.gitignore

-nameただし、ファイル名を一致させる方法を理解していません。
~からman find

   -name pattern
      Base  of  file  name (the path with the leading directories removed) matches shell pattern pattern.  

私にとって、これは-nameパターンがファイル名の最後のセグメントと一致する場合にのみ一致することを意味します。たとえば、-name foo一致します/dir1/dir2/fooいいえ /dir1/dir2/foo/dir3/dir4/some_file 私にとってのポイントは、パス名を持つファイル(たとえば)と-pathパターンを一致させることです。スラッシュ内のセグメントと正確に一致する限り、最後のセグメントだけでなく、ファイルパスのすべてのセグメントと一致するようです。それ以外の場合は、ファイル名を一致させる方法は?foo/dir1/dir2/foo/dir3/dir4/some_file
-name
-name

答え1

.gitディレクトリとその下のすべてを無視するには、次の設定が必要です。

find . \( -name '.git' -prune \) -o \( -print {or whatever else you want to do} \)

これは、その名前のファイルまたはfindディレクトリが見つかったときを示します。.git打つその道をさらに下りるのではなく、木々です。他のすべては、残りの半分の範囲内で一致して処理できます。または条件付き建設。

(括弧の周りのバックスラッシュはシェルがこれを処理するのを防ぎ、この簡単な例では技術的に不要です。明確にするためにそのままにしました。そしてそしてまたはバインディングを設定します。 )

次に、次のフォルダに関する懸念を考慮してくださいfoo

たとえば、一致しますが-name foo一致/dir1/dir2/fooしません。/dir1/dir2/foo/dir3/dir4/some_file

あなたは正しいですが、私はあなたが結果を見逃していると思います。ある時点でfind到達します/dir1/dir2/foo。 willが-name foo一致するため、-prunewillが呼び出されます。それ自体を最初に見ずに下に下る方法はありませんfindfoofoo

したがって、/dir1/dir2/foo/dir3/dir4/some_file決して到達できません。

検査の初期結果はある程度-name foo一致します/dir1/dir2/foo/dir3/dir4/some_fileが、実際には一致し、/dir1/dir2/fooツリーの追加検査は破棄されます。

パスの最後のコンポーネントのみに-name foo一致するものと比較して、フルパスの場合にのみ一致します。 (トップレベルではaと一致することはできますが、決して一致しません。)foo-path foofoofind * -path foofoofind . -path foo./foo

答え2

あなたの理解は-name正しいです。ファイル名のみが一致し、ファイルへのパス(ディレクトリチェーン)は関係ありません。

あなたが逃しているのは効果です-prune。比較済み

find . -name ".git" -o -print 

これは、「呼び出された場合は.git何もせず、そうでない場合はパスを印刷してそのパスに再帰します(ディレクトリの場合)」を意味します。

find . -name ".git" -prune -o -print 

これは「と呼ばれる場合.git、次のことを意味します。繰り返さないでください、そうでない場合は、パスを印刷してそのパスに再帰します(ディレクトリの場合)。

関連情報