すべてのJavaScriptファイルに対してfind
コマンドを実行しようとしていますが、特定のディレクトリを除外するにはどうすればよいですか。
これが私たちが使っているfind
コードです。
for file in $(find . -name '*.js')
do
Java -jar config/yuicompressor-2.4.2.jar --type js $file -o $file
done
たとえば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
です、ただ印刷してください。
-Prune
がうまくいかない場合は、次のようになります。
find -name "*.js" -not -path "./directory/*"
警告: @Danielのコメントを読む。
次のことは、提案されている他のソリューションよりも簡単に推論できます。
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
を指定する必要があります。
1つの選択肢は、grepを含むディレクトリ名を含むすべての結果を除外することです。例えば:
find . -name '*.js' | grep -v excludeddir
これは私のために働いた唯一のものです。
find / -name NameOfFile ! -path '*/Directory/*'
「ディレクトリ」を除く「NameOfFile」を検索しています。星を強調してください*。
私は-not
記法を好みます…もっと読みやすいです:
find . -name '*.js' -and -not -path directory
-Pruneオプションを使用してください。だから、のようなもの:
find . -type d -name proc -Prune -o -name '*.js'
'-type d -name proc -Prune'は、除外するprocという名前のディレクトリのみを探します。
'-o'は 'OR'演算子です。
これは私がいくつかのパスを除外するのに使用したフォーマットです:
$ find ./ -type f -name "pattern" ! -path "excluded path" ! -path "excluded path"
"。*"パスにないすべてのファイルを見つけるためにこれを使いました。
$ find ./ -type f -name "*" ! -path "./.*" ! -path "./*/.*"
-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
-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 \)
良い答えはたくさんありますが、コマンドの各要素の目的とその背後にあるロジックを理解するのに、少し時間がかかりました。
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によっても探索されず、式の後半部分に対してテストされず、出力されません。
複数のディレクトリを除外するには
find . -name '*.js' -not \( -path "./dir1" -o -path "./dir2/*" \)
ディレクトリを追加するには、-o -path "./dirname/*"
を追加します。
find . -name '*.js' -not \( -path "./dir1" -o -path "./dir2/*" -o -path "./dir3/*"\)
ただし、除外するディレクトリが多数ある場合は、 正規表現 を使用する必要があります。
実用的な解決策としては(Ubuntu 12.04(Precise Pangolin)でテスト済み)...
find ! -path "dir1" -iname "*.mp3"
dir1サブフォルダを除く、現在のフォルダとサブフォルダ内のMP3ファイルを検索します。
つかいます:
find ! -path "dir1" ! -path "dir2" -iname "*.mp3"
... dir1 AND dir2を除外する
これを達成するためにPruneオプションを使うことができます。例えばのように:
find ./ -path ./beta/* -Prune -o -iname example.com -print
または逆grepの「grep -v」オプション:
find -iname example.com | grep -v beta
Linuxのfindコマンドでディレクトリを検索対象から除外するに詳しい手順と例があります。
find -name '*.js' -not -path './node_modules/*' -not -path './vendor/*'
と同じように動作するようです
find -name '*.js' -not \( -path './node_modules/*' -o -path './vendor/*' \)
iMOを覚えやすいです。
-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
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
を使うことは頭痛の後に迅速で簡単な解決策でした。
私が必要としていたのは、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
のようなコマンドを実行します/リストの結果
これは私のMacには適しています。
find . -name *.php -or -path "./vendor" -Prune -or -path "./app/cache" -Prune
検索名にvendor
とapp/cache
dirの接尾辞がphp
の場合は除外されます。
find . -name '*.js' -\! -name 'glob-for-excluded-dir' -Prune
これまでの答えはどれもUbuntuには向かない。これを試して:
find . ! -path "*/test/*" -type f -name "*.js" ! -name "*-min-*" ! -name "*console*"
私はこれを見つけました ここ
-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/
を複数回入力しないようにするには、find
をpushd .. 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
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
のマニュアルページの「例」セクションから
私は上記のコマンドを試してみましたが、 "-Prune"を使っている人は私にはうまくいきません。結局、私は以下のコマンドでこれを試しました:
find . \( -name "*" \) -Prune -a ! -name "directory"
私は、Cソースファイルの関数名がexclude * .oとexclude * .swpおよびexclude(通常のファイルではない)を見つけ、次のコマンドでdir出力を除外しました。
find . \( ! -path "./output/*" \) -a \( -type f \) -a \( ! -name '*.o' \) -a \( ! -name '*.swp' \) | xargs grep -n soc_attach
ここにはすでにたくさんの答えがあります。私は別のものを追加することを躊躇しますが、私はこの情報が役に立つと思います。
TLDR: "-Prune
"オプションを使用して、ルートディレクトリを理解し、そこから検索を調整します。
背景: rsnapshot
(rsync
)バックアップの場所/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
$
これですべてのEdgeのケースがカバーされるかどうかはわかりませんが、次の手順は非常に簡単で、試すのは簡単です。
ls -1|grep -v -e ddl -e docs| xargs rm -rf
これにより、現在のディレクトリからすべてのファイル/ディレクトリが削除されます( 'ddls'および 'docs')。
検索ディレクトリにパターンがある場合(私の場合はほとんどの場合)。あなたは単に以下のようにそれをすることができます:
find ./n* -name "*.tcl"
上記の例では"n"で始まるすべてのサブディレクトリを検索します。
FreeBSD usersの場合:
find . -name '*.js' -not -path '*exclude/this/dir*'
これは、find
テストがパターン " * foo * "のファイルであるために機能します。
find ! -path "dir1" ! -path "dir2" -name "*foo*"
ただし、パターンを使用しない場合は、NOTは機能します(find
はTESTファイルではありません)。そのため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
よろしく
私はこのページの提案を見つけました、そして他の多くのページは私の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分かかります。これらの除外がなければ、何時間もかかります。