shで「検索」の「 - プルーネ」オプションを使用する方法は?
質問
私はから与えられた例をよく理解していません man find
, 、誰かが私にいくつかの例と説明をすることができますか?その中に正規表現を組み合わせることはできますか?
より詳細な質問は次のようです:
シェルスクリプトを書く、 changeall
, 、次のインターフェイスがあります changeall [-r|-R] "string1" "string2"
. 。接尾辞が付いたすべてのファイルがあります .h
, .C
, .cc
, 、 また .cpp
のすべての発生を変更します string1
に string2
. -r
現在の監督のみに留まるか、サブディルを含むオプションです。
ノート:
- 非再帰的な場合、
ls
許可されていないため、使用することしかできませんでしたfind
とsed
. - 私は試した
find -depth
しかし、それはサポートされていませんでした。だから私は疑問に思っていました-prune
役立つかもしれませんが、例を理解していませんでしたman find
.
edit2:私は割り当てをしていました、私はそれを自分で終えたいので、私はそれを詳細に質問しませんでした。私はすでにそれをやっていて、それを手渡したので、今私は質問全体を述べることができます。また、私はなんとか使用せずに割り当てを完了することができました -prune
, 、しかし、とにかくそれを学びたいです。
解決
混乱していることがわかりました -prune
それはアクションであるということです( -print
)、テストではありません(次のように -name
)。 「To Do」リストを変更します。 しかし、常に真実を返します.
使用するための一般的なパターン -prune
これは:
find [path] [conditions to prune] -prune -o \
[your usual conditions] [actions to perform]
あなたはほとんどずっと欲しいです -o
(論理または)直後 -prune
, 、テストの最初の部分が -prune
) 戻ります 間違い あなたが実際に望むもののために(つまり:あなたが しないでください 剪定したい)。
これが例です:
find . -name .snapshot -prune -o -name '*.foo' -print
これにより、「.snapshot」ディレクトリの下にない「*.foo」ファイルが見つかります。この例では、 -name .snapshot
を構成します [conditions to prune]
, 、 と -name '*.foo' -print
は [your usual conditions]
と [actions to perform]
.
重要なメモ:
あなたがしたいのは、あなたが除外することに慣れているかもしれない結果を印刷するだけなら
-print
アクション。あなたは一般的に しないでください 使用するときにそれをしたい-prune
.発見のデフォルトの動作は「と」です 全体 での表現
-print
アクション以外のアクションがない場合-prune
(皮肉なことに)最後に。それはこれを書くことを意味します:find . -name .snapshot -prune -o -name '*.foo' # DON'T DO THIS
これを書くことに相当します:
find . \( -name .snapshot -prune -o -name '*.foo' \) -print # DON'T DO THIS
つまり、剪定しているディレクトリの名前も印刷されます。これは通常、あなたが望むものではありません。代わりに、明示的に指定する方が良いです
-print
それがあなたが望むものである場合のアクション:find . -name .snapshot -prune -o -name '*.foo' -print # DO THIS
あなたの「通常の状態」があなたのプルーン状態にも一致するファイルと一致する場合、それらのファイルは いいえ 出力に含まれます。これを修正する方法は、aを追加することです
-type d
剪定状態に述べています。たとえば、始まったディレクトリを剪定したいとしたとします
.git
(これは明らかにやや不自然です - 通常、あなたは名前が付けられたものを削除するだけです まさに.git
)、しかし、それ以外は、次のようなファイルを含むすべてのファイルを見たいと思っていました.gitignore
. 。あなたはこれを試すかもしれません:find . -name '.git*' -prune -o -type f -print # DON'T DO THIS
これはそうでしょう いいえ 含む
.gitignore
出力内。これが固定バージョンです:find . -type d -name '.git*' -prune -o -type f -print # DO THIS
追加のヒント:GNUバージョンを使用している場合 find
, 、texinfoページ find
マンページよりも詳細な説明があります(ほとんどのGNUユーティリティに当てはまります)。
他のヒント
-pruneが降順を妨げないことに注意してください どれか 一部の人が言ったようにディレクトリ。適用されているテストに一致するディレクトリへの降順を防ぎます。おそらくいくつかの例が役立つでしょう(正規表現の例については、底を参照してください)。これがとても長くなってすみません。
$ find . -printf "%y %p\n" # print the file type the first time FYI
d .
f ./test
d ./dir1
d ./dir1/test
f ./dir1/test/file
f ./dir1/test/test
d ./dir1/scripts
f ./dir1/scripts/myscript.pl
f ./dir1/scripts/myscript.sh
f ./dir1/scripts/myscript.py
d ./dir2
d ./dir2/test
f ./dir2/test/file
f ./dir2/test/myscript.pl
f ./dir2/test/myscript.sh
$ find . -name test
./test
./dir1/test
./dir1/test/test
./dir2/test
$ find . -prune
.
$ find . -name test -prune
./test
./dir1/test
./dir2/test
$ find . -name test -prune -o -print
.
./dir1
./dir1/scripts
./dir1/scripts/myscript.pl
./dir1/scripts/myscript.sh
./dir1/scripts/myscript.py
./dir2
$ find . -regex ".*/my.*p.$"
./dir1/scripts/myscript.pl
./dir1/scripts/myscript.py
./dir2/test/myscript.pl
$ find . -name test -prune -regex ".*/my.*p.$"
(no results)
$ find . -name test -prune -o -regex ".*/my.*p.$"
./test
./dir1/test
./dir1/scripts/myscript.pl
./dir1/scripts/myscript.py
./dir2/test
$ find . -regex ".*/my.*p.$" -a -not -regex ".*test.*"
./dir1/scripts/myscript.pl
./dir1/scripts/myscript.py
$ find . -not -regex ".*test.*" .
./dir1
./dir1/scripts
./dir1/scripts/myscript.pl
./dir1/scripts/myscript.sh
./dir1/scripts/myscript.py
./dir2
通常、私たちがLinuxで物事を行うネイティブの方法と、私たちが考える方法は左から右へです。
だからあなたはあなたが最初に探しているものを書いて書くでしょう:
find / -name "*.php"
それから、おそらくEnterを押して、あなたが望んでいないディレクトリからあまりにも多くのファイルを取得していることに気付くでしょう。取り付けられたドライブの検索を避けるために、メディアを除外しましょう。
これで、以下を前のコマンドに追加するだけです。
-print -o -path '/media' -prune
したがって、最終コマンドは次のとおりです。
find / -name "*.php" -print -o -path '/media' -prune
............... | <--- include ---> | .................... | < - --------除外----------> |
この構造ははるかに簡単で、正しいアプローチと相関していると思います
他の回答で与えられたアドバイスに追加されます(返信を作成する担当者はいません)...
結合するとき -prune
他の表現では、他の式が使用されるものに応じて、動作に微妙な違いがあります。
@laurence Gonsalvesの例では、「*.foo」ファイルが「.snapshot」ディレクトリを見つけます: -
find . -name .snapshot -prune -o -name '*.foo' -print
ただし、このわずかに異なる短い手は、おそらく不注意に、 .snapshot
ディレクトリ(およびネストされた.snapshotディレクトリ): -
find . -name .snapshot -prune -o -name '*.foo'
その理由は(私のシステムのマンページによると): -
与えられた式にプライマリー-EXEC、-LS、-OK、または-PRINTのいずれかが含まれていない場合、与えられた式は次のことに効果的に置き換えられます。
(与えられた_Expression)-print
つまり、2番目の例は、以下を入力するのと同等であり、それによって用語のグループ化を変更することです。
find . \( -name .snapshot -prune -o -name '*.foo' \) -print
これは少なくともSolaris 5.10で見られています。 *nixのさまざまなフレーバーを約10年間使用していたので、これが発生する理由を検索したことがあります。
Pruneは、どのディレクトリスイッチで再発しないでください。
マンページから
-depthが与えられていない場合、TRUE;ファイルがディレクトリの場合、それに入らないでください。 -depthが与えられた場合、false;無効。
基本的に、それはどのサブディレクトリにも抑えられません。
この例を取ります:
次のディレクトリがあります
- /home/test2
- /home/test2/test2
走ったら find -name test2
:
両方のディレクトリを返します
走ったら find -name test2 -prune
:
/home/test2に下降しないため、/home/test2のみ/home/test2に戻ります/home/test2/test2
私はこれの専門家ではありません(そして、このページは一緒に非常に役に立ちました http://mywiki.wooledge.org/usingfind)
気づきました -path
その道です 直後に来る文字列/パスに完全に一致します find
(.
これらの例では)as -name
すべてのベースネームに一致します。
find . -path ./.git -prune -o -name file -print
現在のディレクトリの.gitディレクトリをブロックします ( あなたの発見として .
)
find . -name .git -prune -o -name file -print
すべての.gitサブディレクトリを再帰的にブロックします。
注意してください ./
非常に重要です!! -path
固定されたパスに一致する必要があります .
または見つけた直後に来るものは何でも あなたがそれと一致するなら(またはの反対側から」-o
')おそらく剪定されていないでしょう!私はこれを素朴に気づいていなかったので、同じベースネームですべてのサブディレクトリを剪定したくないときに、それが素晴らしいときにパスを使用することになりました:D
dir自体を含むすべてを示しますが、その長い退屈な内容ではありません。
find . -print -name dir -prune
ここですべての良い答えを読むと、私の理解は、次のすべてが同じ結果を返すということです。
find . -path ./dir1\* -prune -o -print
find . -path ./dir1 -prune -o -print
find . -path ./dir1\* -o -print
#look no prune at all!
しかし 最後の1つは、DIR1のすべてを検索しているため、ずっと時間がかかります。本当の質問は方法だと思います -or
実際にそれらを検索することなく、不要な結果を出します。
だから私はプルーンは過去の試合をまともではないが、それを完了したとおりにマークすることを意味すると思います...
http://www.gnu.org/software/findutils/manual/html_mono/find.html「しかし、これは「 - プルーネ」アクションの影響によるものではありません(これはさらなる降下を防ぐだけで、そのアイテムを無視することを確認しません)。代わりに、この効果は「-O」の使用によるものです。 「または」条件の左側は./SRC/EMACSで成功したため、この特定のファイルについては右側( '-print')をまったく評価する必要はありません。」
find
ファイルのリストを作成します。それはあなたがそれぞれに提供した述語を適用し、通過するものを返します。
この考え -prune
結果から除外された手段は、私にとって本当に混乱していました。プルーンなしでファイルを除外できます。
find -name 'bad_guy' -o -name 'good_guy' -print // good_guy
全て -prune
検索の動作を変更することです。現在の一致がディレクトリである場合、 "おい find
, 、あなたがちょうど一致したファイル、それに降りてはいけません」. 。検索するファイルのリストからそのツリー(ファイル自体ではなく)を削除するだけです。
名前の名前を付けてください -dont-descend
.