web-dev-qa-db-ja.com

Findでディレクトリを除外する方法コマンド

すべてのJavaScriptファイルに対してfindコマンドを実行しようとしていますが、特定のディレクトリを除外するにはどうすればよいですか。

これが私たちが使っているfindコードです。

for file in $(find . -name '*.js')
do 
  Java -jar config/yuicompressor-2.4.2.jar --type js $file -o $file
done
1108
helion3

たとえばmiscディレクトリを除外したい場合は、Pruneスイッチを使用します。検索コマンドに-path ./misc -Prune -oを追加するだけです。

find . -path ./misc -Prune -o -name '*.txt' -print

これは複数のディレクトリを持つ例です。

find . -type d \( -path dir1 -o -path dir2 -o -path dir3 \) -Prune -o -print

ここでは、dir1、dir2、およびdir3を除外しています。これは、find式では、基準-path dir1 -o -path dir2 -o -path dir3(dir1またはdir2またはdir3の場合)に基づいて動作するアクションであり、type -dとAND演算されるためです。さらなる行動は-o printです、ただ印刷してください。

853
f10bit

-Pruneがうまくいかない場合は、次のようになります。

find -name "*.js" -not -path "./directory/*"

警告: @Danielのコメントを読む。

1727
GetFree

次のことは、提案されている他のソリューションよりも簡単に推論できます。

find build -not \( -path build/external -Prune \) -name \*.js
# you can also exclude multiple paths
find build -not \( -path build/external -Prune \) -not \( -path build/blog -Prune \) -name \*.js

重要な注意:-pathの後に入力するパスは、findが除外なしで出力するものと完全に一致する必要があります。この文が混乱する場合は、必ずfind /full/path/ -not \( -path /full/path/exclude/this -Prune \) ...のようにwholeコマンド全体でフルパスを使用してください。理解を深めるには、注[1]を参照してください。

\(\)の中には、exactlybuild/external(上記の重要な注意事項を参照)と一致する式があり、成功すると以下のものを横断しないようにしてください。次に、これはエスケープされた括弧で単一の式としてグループ化され、findがその式に一致したものをすべてスキップする-notがプレフィックスとして付けられます。

-notを追加しても、他のすべてのファイルが-Pruneによって非表示にならないので、答えはノーです。 -Pruneが機能する方法は、一度到達すると、そのディレクトリの下のファイルは永久に無視されるということです。

これは、wintersmithによって生成された一部のファイルでyui-compressorを呼び出す必要があったが、そのまま送信する必要のある他のファイルを除外する実際の使用例から来ています。


注[1]/tmp/foo/barを除外したいときに、この「find /tmp \(...」のようにfindを実行する場合は、-path /tmp/foo/barを指定する必要があります。一方、このcd /tmp; find . \(...のようにfindを実行する場合は、-path ./foo/barを指定する必要があります。

422

1つの選択肢は、grepを含むディレクトリ名を含むすべての結果を除外することです。例えば:

find . -name '*.js' | grep -v excludeddir
55
Joshua

これは私のために働いた唯一のものです。

find / -name NameOfFile ! -path '*/Directory/*'

「ディレクトリ」を除く「NameOfFile」を検索しています。星を強調してください*。

42
DimiDak

私は-not記法を好みます…もっと読みやすいです:

find . -name '*.js' -and -not -path directory
39
mpapis

-Pruneオプションを使用してください。だから、のようなもの:

find . -type d -name proc -Prune -o -name '*.js'

'-type d -name proc -Prune'は、除外するprocという名前のディレクトリのみを探します。
'-o'は 'OR'演算子です。

18
Drew Frezell

これは私がいくつかのパスを除外するのに使用したフォーマットです:

$ find ./ -type f -name "pattern" ! -path "excluded path" ! -path "excluded path"

"。*"パスにないすべてのファイルを見つけるためにこれを使いました。

$ find ./ -type f -name "*" ! -path "./.*" ! -path "./*/.*"
14
user1882879

-Pruneは間違いなく機能し、最良の答えです。なぜなら、それはあなたが除外したいディレクトリに降りるのを妨げるからです。まだ除外ディレクトリを検索する-not -pathは、結果を表示しません。除外ディレクトリがネットワークボリュームにマウントされているか、権限がない場合、これは問題になる可能性があります。

注意が必要なのは、findは引数の順序に非常に細心の注意を払うことです。引数の順序は一般に以下のとおりです。

find {path} {options} {action}

{path}. -path './dir1' -Prune -oのように、すべてのパス関連の引数を最初に置く

{options}:このグループの最後のオプションとして-name, -iname, etcを入れたとき、私は最も成功しました。例えば。 -type f -iname '*.js'

{action}-printを使うときは-Pruneを追加したいでしょう

これが実用的な例です。

# setup test
mkdir dir1 dir2 dir3
touch dir1/file.txt; touch dir1/file.js
touch dir2/file.txt; touch dir2/file.js
touch dir3/file.txt; touch dir3/file.js

# search for *.js, exclude dir1
find . -path './dir1' -Prune -o -type f -iname '*.js' -print

# search for *.js, exclude dir1 and dir2
find . \( -path './dir1' -o -path './dir2' \) -Prune -o -type f -iname '*.js' -print
13
wisbucky

-path -Pruneアプローチは、パス内のワイルドカードに対しても機能します。これは、git内部ディレクトリを除外して、複数のgitリポジトリに対応しているgitサーバーのディレクトリを見つけるfindステートメントです。

find . -type d \
   -not \( -path */objects -Prune \) \
   -not \( -path */branches -Prune \) \
   -not \( -path */refs -Prune \) \
   -not \( -path */logs -Prune \) \
   -not \( -path */.git -Prune \) \
   -not \( -path */info -Prune \) \
   -not \( -path */hooks -Prune \)  
9
Wolfgang Fahl

良い答えはたくさんありますが、コマンドの各要素の目的とその背後にあるロジックを理解するのに、少し時間がかかりました。

find . -path ./misc -Prune -o -name '*.txt' -print

findは現在のディレクトリ、つまりfind .内のファイルとディレクトリの検索を開始します。

-oオプションは論理ORを表し、コマンドの2つの部分を区切ります。

[ -path ./misc -Prune ] OR [ -name '*.txt' -print ]

not ./miscディレクトリであるディレクトリまたはファイルは、最初のテスト-path ./miscに合格しません。しかし、それらは2番目の式に対してテストされます。それらの名前が*.txtオプションのためにそれらが印刷されるパターン-printに対応するならば。

Findが./miscディレクトリに達すると、このディレクトリは最初の式のみを満たします。そのため-Pruneオプションが適用されます。それはfindコマンドに not そのディレクトリを探索するように伝えます。そのため、./misc内のファイルやディレクトリはfindによっても探索されず、式の後半部分に対してテストされず、出力されません。

8
Istopopoki

複数のディレクトリを除外するには

find . -name '*.js' -not \( -path "./dir1" -o -path "./dir2/*" \)

ディレクトリを追加するには、-o -path "./dirname/*"を追加します。

find . -name '*.js' -not \( -path "./dir1" -o -path "./dir2/*" -o -path "./dir3/*"\)

ただし、除外するディレクトリが多数ある場合は、 正規表現 を使用する必要があります。

8
JBENOIT

実用的な解決策としては(Ubuntu 12.04(Precise Pangolin)でテスト済み)...

find ! -path "dir1" -iname "*.mp3"

dir1サブフォルダを除く、現在のフォルダとサブフォルダ内のMP3ファイルを検索します。

つかいます:

find ! -path "dir1" ! -path "dir2" -iname "*.mp3"

... dir1 AND dir2を除外する

7
james dupin

これを達成するためにPruneオプションを使うことができます。例えばのように:

find ./ -path ./beta/* -Prune -o -iname example.com -print

または逆grepの「grep -v」オプション:

find -iname example.com | grep -v beta

Linuxのfindコマンドでディレクトリを検索対象から除外するに詳しい手順と例があります。

6
Siju V
find -name '*.js' -not -path './node_modules/*' -not -path './vendor/*'

と同じように動作するようです

find -name '*.js' -not \( -path './node_modules/*' -o -path './vendor/*' \)

iMOを覚えやすいです。

4
Funkodebat

-path または -not を使用できない古いバージョンのUNIXを使用している人のためのものです。

SunOS 5.10 bash 3.2およびSunOS 5.11 bash 4.4でテスト済み

find . -type f -name "*" -o -type d -name "*excluded_directory*" -Prune -type f
3
JaredTS486

findのファイルのリストを提供するためにxgettextを使用していましたが、特定のディレクトリとその内容を省略したいと考えました。私は-path-Pruneと組み合わせて多くの順列を試してみましたが、私が行っていたディレクトリを完全に除外することはできませんでした。

無視したいディレクトリの contents を無視することはできましたが、findは結果の1つとしてディレクトリ自体を返すため、結果としてxgettextがクラッシュしていました(ディレクトリを受け付けず、ファイルのみ)。 。

私の解決策は、単にgrep -vを使用して、結果に不要なディレクトリをスキップすることでした。

find /project/directory -iname '*.php' -or -iname '*.phtml' | grep -iv '/some/directory' | xargs xgettext

findに100%有効な引数があるかどうかに関係なく、私は確かに言うことはできません。 grepを使うことは頭痛の後に迅速で簡単な解決策でした。

3
Lemmings19

私が必要としていたのは、rootから始めてlandscape.jpgディレクトリでの検索を除いて、すべてのサーバーで/varを見つけることです。

find / -maxdepth 1 -type d | grep -v /var | xargs -I '{}' find '{}' -name landscape.jpg

find / -maxdepth 1 -type dは、/内のすべての d irectoriesをリストします。

grep -v /varはリストから `/ var 'を除外します

xargs -I '{}' find '{}' -name landscape.jpgは各ディレクトリでfindのようなコマンドを実行します/リストの結果

2
adrianTNT

これは私のMacには適しています。

find . -name *.php -or -path "./vendor" -Prune -or -path "./app/cache" -Prune

検索名にvendorapp/cache dirの接尾辞がphpの場合は除外されます。

2
jiahut
find . -name '*.js' -\! -name 'glob-for-excluded-dir' -Prune
2

これまでの答えはどれもUbuntuには向かない。これを試して:

find . ! -path "*/test/*" -type f -name "*.js" ! -name "*-min-*" ! -name "*console*"

私はこれを見つけました ここ

2
sixro

-Pruneのしくみについて Laurence Gonsalves は、 sh-in-findの使い方のプルーニングオプション から得られる優れた答えです。

そして、これが一般的な解決策です:

find /path/to/search                    \
  -type d                               \
    \( -path /path/to/search/exclude_me \
       -o                               \
       -name exclude_me_too_anywhere    \
     \)                                 \
    -Prune                              \
  -o                                    \
  -type f -name '*\.js' -print

/path/to/seach/を複数回入力しないようにするには、findpushd .. popdのペアで囲みます。

pushd /path/to/search;                  \
find .                                  \
  -type d                               \
    \( -path ./exclude_me               \
       -o                               \
       -name exclude_me_too_anywhere    \
     \)                                 \
    -Prune                              \
  -o                                    \
  -type f -name '*\.js' -print;         \
 popd
1
go2null

execループよりforアクションを使用するほうが良いでしょう。

find . -path "./dirtoexclude" -Prune \
    -o -exec Java -jar config/yuicompressor-2.4.2.jar --type js '{}' -o '{}' \;

exec ... '{}' ... '{}' \;は、一致するファイルごとに1回実行され、中括弧'{}'は現在のファイル名に置き換えられます。

シェルスクリプト句読点として解釈されないように中括弧が単一引用符で囲まれていることに注意してください。*


ノート

* find (GNU findutils) 4.4.2のマニュアルページの「例」セクションから

1
Alberto

私は上記のコマンドを試してみましたが、 "-Prune"を使っている人は私にはうまくいきません。結局、私は以下のコマンドでこれを試しました:

find . \( -name "*" \) -Prune -a ! -name "directory"
1
Jolly Liu

私は、Cソースファイルの関数名がexclude * .oとexclude * .swpおよびexclude(通常のファイルではない)を見つけ、次のコマンドでdir出力を除外しました。

find .  \( ! -path "./output/*" \) -a \( -type f \) -a \( ! -name '*.o' \) -a \( ! -name '*.swp' \) | xargs grep -n soc_attach
1
Ivan Ivanovich

ここにはすでにたくさんの答えがあります。私は別のものを追加することを躊躇しますが、私はこの情報が役に立つと思います。

TLDR: "-Prune"オプションを使用して、ルートディレクトリを理解し、そこから検索を調整します。

背景: rsnapshotrsync)バックアップの場所/mnt/Backups/があります。これは、システム(/)ファイルの検索時に頭痛の原因となります。

私はまた、TB個のファイルがある私のメイン作業フォルダである/mnt/Vancouverを持っています。これは[/mnt/Backups//mnt/Vancouver/は物理的に(冗長的に)別々のドライブにマウントされています]。


ここでの2つの答えのうち( find。コマンドでディレクトリを除外する方法 )、受け入れられた答えを使用してシステムファイルを検索する方が、 はるか 高速であることがわかります。

これです

find / -path /mnt -Prune -o -name "*libname-server-2.a*" -print

3〜4秒でそのファイルを見つけます。これです

find / -name "*libname-server-2.a*" -not -path "/mnt/*"

除外されたすべてのディレクトリ(マウントされたすべてのボリュームのrsyncスナップショット)を再帰処理するように(?)が表示されるので、 forever が必要です。私はそれが数TBのファイルを検索していると推測しているので、それはずいぶん駄目になっています。たとえば、その検索( "time find ...")を "計時"しようとすると、大量の出力が表示されます - findが "excluded"ディレクトリを深く横断していることを示唆しています。

...
find: ‘/mnt/Backups/rsnapshot_backups/monthly.0/snapshot_root/var/lib/udisks2’: Permission denied
...

除外されたディレクトリ(/mnt/)またはネストされたパス( `/ mnt/Backups ')の後にスラッシュを追加すると、検索は 再び* になります。

遅い:

find / -path /mnt/ -Prune -o -name "*libname-server-2.a*" -print
find / -path /mnt/Vancouver -Prune -o -name "*libname-server-2.a*" -print

"SOLUTION"

これが最善の解決策です(これらはすべて数秒で実行されます)。繰り返しますが、私のディレクトリ構造は

  • /:root
  • /mnt/Backups/:マルチTBバックアップ
  • /mnt/Vancouver/:複数TBの作業ディレクトリ(別のドライブにある/mnt/Backupsにバックアップされています)、よく検索したいディレクトリ
  • /home/*:他のマウントポイント/作業中の「ドライブ」(例:/home/victoria = ~

システムファイル(/):

システムファイルをすばやく見つけるには、/mntを除外します( NOT /mnt/または/mnt/Backups、...)。

$ find / -path /mnt -Prune -o -name "*libname-server-2.a*" -print
/usr/lib/libname-server-2.a

そのファイルは3〜4秒で見つかります。

システムファイル以外のファイル:

例えば。 /mnt/Vancouver//home/victoria/、あるいはその両方で動作している2つの「ドライブ」のいずれかでファイルをすばやく見つけることができます。

$ find /mnt/Vancouver/ -name "*04t8ugijrlkj.jpg"
/mnt/Vancouver/temp/04t8ugijrlkj.jpg

$ find /home/victoria -iname "*Untitled Document 1"
/home/victoria/backups/shortcuts.bak.2016.11.02/Untitled Document 1
/home/victoria/Untitled Document 1

バックアップ:

例えば。私の毎時/毎日/毎週/毎月のバックアップのいずれかで、削除されたファイルを見つけるために)。

$ find /mnt/Backups/rsnapshot_backups/daily.0 -name "*04t8ugijrlkj.jpg"
/mnt/Backups/rsnapshot_backups/daily.0/snapshot_root/mnt/Vancouver/temp/04t8ugijrlkj.jpg 

脇に: コマンドの最後に-printを追加すると、除外されたディレクトリの印刷が抑制されます。

$ find / -path /mnt -Prune -o -name "*libname-server-2.a*"
/mnt
/usr/lib/libname-server-2.a

$ find / -path /mnt -Prune -o -name "*libname-server-2.a*" -print
/usr/lib/libname-server-2.a
$ 
1
Victoria Stuart

これですべてのEdgeのケースがカバーされるかどうかはわかりませんが、次の手順は非常に簡単で、試すのは簡単です。

ls -1|grep -v -e ddl -e docs| xargs rm -rf

これにより、現在のディレクトリからすべてのファイル/ディレクトリが削除されます( 'ddls'および 'docs')。

0
Arnab

検索ディレクトリにパターンがある場合(私の場合はほとんどの場合)。あなたは単に以下のようにそれをすることができます:

find ./n* -name "*.tcl" 

上記の例では"n"で始まるすべてのサブディレクトリを検索します。

0
Prince Bhanwra

FreeBSD usersの場合:

 find . -name '*.js' -not -path '*exclude/this/dir*'
0

これは、findテストパターン " * foo * "のファイルであるために機能します。

find ! -path "dir1" ! -path "dir2" -name "*foo*"

ただし、パターンを使用しない場合は、NOTは機能します(findTESTファイルではありません)。そのためfindは以前に評価された " true "& " false "ブール値を使用しません。上記の表記法でうまく機能しないユースケースの例:

find ! -path "dir1" ! -path "dir2" -type f

findテストはありません。そのため、パターンマッチングなしでファイルを探す必要がある場合は、-Pruneを使用してください。また、Prune findを使用すると、常に一致するのではなく、一致しないよりもそのディレクトリをスキップするため、常に高速になります。その場合は、次のようにします。

find dir -not \( -path "dir1" -Prune \) -not \( -path "dir2" -Prune \) -type f

または

find dir -not \( -path "dir1" -o -path "dir2" -Prune \) -type f

よろしく

0
d0n

私はこのページの提案を見つけました、そして他の多くのページは私のMac OS Xシステムでは動作しません。しかし、私は私のために働くバリエーションを見つけました。

大きなアイデアは、Macintosh HDを検索しながら、主にTime Machineバックアップ、イメージバックアップ、マウントされた共有、およびアーカイブであるすべての外部ボリュームを調べないようにすることです。

これが私の実用的なスクリプトで、それを "findit"と名付けました。

#!/usr/bin/env bash
# inspired by http://stackoverflow.com/questions/4210042/exclude-directory-from-find-command Danile C. Sobral
# using special syntax to avoid traversing. 
# However, logic is refactored because the Sobral version still traverses 
# everything on my system

echo ============================
echo find - from cwd, omitting external volumes
date
echo Enter Sudo password if requested
Sudo find . -not \( \
-path ./Volumes/Archive -Prune -o \
-path ./Volumes/Boot\ OS\ X -Prune -o \
-path ./Volumes/C \
-path ./Volumes/Data -Prune -o \
-path ./Volumes/jas -Prune -o \
-path ./Volumes/Recovery\ HD -Prune -o \
-path ./Volumes/Time\ Machine\ Backups -Prune -o \
-path ./Volumes/SuperDuper\ Image -Prune -o \
-path ./Volumes/userland -Prune \
\) -name "$1" -print
date
echo ============================
iMac2:~ jas$

さまざまなパスは、外部アーカイブボリューム、Time Machine、仮想マシン、その他のマウントされたサーバーなどに関係しています。一部のボリューム名にはスペースが含まれています。

このファイルは私のシステムの多くの場所にあるので、良いテスト実行は "findit index.php"です。このスクリプトでは、メインハードドライブを検索するのに約10分かかります。これらの除外がなければ、何時間もかかります。

0
Jeffrey Simon