で終わるファイルを見つけたいの_peaks.bed
ですが、フォルダー内のファイルを除外tmp
しscripts
ます。
私のコマンドは次のようなものです:
find . -type f \( -name "*_peaks.bed" ! -name "*tmp*" ! -name "*scripts*" \)
しかし、それはうまくいきませんでした。tmp
およびscript
フォルダ内のファイルは引き続き表示されます。
誰かがこれについてアイデアを持っていますか?
回答:
これを次のように指定する方法は次のfind
とおりです。
find . -type f -name "*_peaks.bed" ! -path "./tmp/*" ! -path "./scripts/*"
説明:
find .
-現在の作業ディレクトリから検索を開始します(デフォルトでは再帰的に)-type f
-find
結果にファイルのみが必要であることを指定します-name "*_peaks.bed"
-名前がで終わるファイルを探します _peaks.bed
! -path "./tmp/*"
-パスがで始まるすべての結果を除外します ./tmp/
! -path "./scripts/*"
-パスがで始まるすべての結果も除外します ./scripts/
ソリューションのテスト:
$ mkdir a b c d e
$ touch a/1 b/2 c/3 d/4 e/5 e/a e/b
$ find . -type f ! -path "./a/*" ! -path "./b/*"
./d/4
./c/3
./e/a
./e/b
./e/5
あなたはかなり近かった、-name
オプションはベース名のみを考慮します-path
が、パス全体を考慮します=)
find
が、質問にはLinuxのタグが付けられているため、問題はありません。いい答えだ。
.
最初の検索プロンプトで使用する場合は、除外する各パスで使用する必要があります。パスマッチングはかなり厳密で、あいまい検索は行いません。したがって、使用すると機能find / -type f -name *.bed" ! -path "./tmp/"
しなくなります。あなたは! -path "/tmp"
それを幸せにする必要があります。
$ ! -path "./directory/*"
-prune
は、ツリー内のすべてのファイルをチェックするのではなく、を使用します。」除外したディレクトリが非常に深く実行されているか、大量のファイルがあり、パフォーマンスが気になる場合は、-prune
代わりにこのオプションを使用してください。
これがあなたがそれをすることができる1つの方法です...
find . -type f -name "*_peaks.bed" | egrep -v "^(./tmp/|./scripts/)"
find
GNUだけでなく、の任意のバージョンで作業できるというメリットがありますfind
。ただし、質問にはLinuxのタグが付けられているため、重要ではありません。
使用する
find \( -path "./tmp" -o -path "./scripts" \) -prune -o -name "*_peaks.bed" -print
または
find \( -path "./tmp" -o -path "./scripts" \) -prune -false -o -name "*_peaks.bed"
または
find \( -path "./tmp" -path "./scripts" \) ! -prune -o -name "*_peaks.bed"
順序は重要です。左から右に評価します。常にパスの除外から始めます。
ディレクトリ全体を除外するために-not
(または!
)を使用しないでください。を使用し-prune
ます。マニュアルで説明されているように:
−prune The primary shall always evaluate as true; it
shall cause find not to descend the current
pathname if it is a directory. If the −depth
primary is specified, the −prune primary shall
have no effect.
そしてGNU検索マニュアルで:
-path pattern
[...]
To ignore a whole
directory tree, use -prune rather than checking
every file in the tree.
実際、を使用すると-not -path "./pathname"
、findは"./pathname"
。の下の各ノードの式を評価します。
検索式は単なる条件評価です。
\( \)
-グループ操作(を使用できますが-path "./tmp" -prune -o -path "./scripts" -prune -o
、より冗長です)。-path "./script" -prune
-場合は-path
trueを返し、ディレクトリで、そのディレクトリについてtrueを返すとないではない、それに降り。-path "./script" ! -prune
-として評価され(-path "./script") AND (! -prune)
ます。プルーンの「常に真」を常に偽に戻します。"./script"
一致としての印刷を回避します。-path "./script" -prune -false
--prune
常にtrueを返すので、それに続いてと-false
同じことを行うことができます!
。-o
-OR演算子。2つの式の間に演算子が指定されていない場合、デフォルトでAND演算子になります。したがって、次のよう\( -path "./tmp" -o -path "./scripts" \) -prune -o -name "*_peaks.bed" -print
に拡張されます。
[ (-path "./tmp" OR -path "./script") AND -prune ] OR ( -name "*_peaks.bed" AND print )
印刷は次のように展開されるため、ここでは重要です。
{ [ (-path "./tmp" OR -path "./script" ) AND -prune ] OR (-name "*_peaks.bed" ) } AND print
-print
findによって追加されます-そのため、ほとんどの場合、式に追加する必要はありません。また、-prune
trueを返すため、「。/script」と「./tmp」を出力します。
-prune
常にfalseを返すように切り替えたため、他の場合は必要ありません。
ヒント:を使用find -D opt expr 2>&1 1>/dev/null
して、最適化および拡張された方法を確認したり、
find -D search expr 2>&1 1>/dev/null
チェックされているパスを確認したりできます。
私にとって、このソリューションはfindを使用したコマンドexecで機能しませんでした。理由はよくわかりません。したがって、私のソリューションは
find . -type f -path "./a/*" -prune -o -path "./b/*" -prune -o -exec gzip -f -v {} \;
説明: sampson-chenのものと同じですが、
-prune-の手順パスを無視します...
-o-一致するものがない場合は、結果を出力します(ディレクトリを整理し、残りの結果を出力します)
18:12 $ mkdir a b c d e
18:13 $ touch a/1 b/2 c/3 d/4 e/5 e/a e/b
18:13 $ find . -type f -path "./a/*" -prune -o -path "./b/*" -prune -o -exec gzip -f -v {} \;
gzip: . is a directory -- ignored
gzip: ./a is a directory -- ignored
gzip: ./b is a directory -- ignored
gzip: ./c is a directory -- ignored
./c/3: 0.0% -- replaced with ./c/3.gz
gzip: ./d is a directory -- ignored
./d/4: 0.0% -- replaced with ./d/4.gz
gzip: ./e is a directory -- ignored
./e/5: 0.0% -- replaced with ./e/5.gz
./e/a: 0.0% -- replaced with ./e/a.gz
./e/b: 0.0% -- replaced with ./e/b.gz
find . -path ./scripts -prune -name '*_peaks.bed' -type f
。複数のディレクトリを除外する方法がわからない。これには、type
指定されている場合でも、最上位の除外ディレクトリも一覧表示されます。pruneを使用して検索操作を高速化する場合を除いて、Grep経由での除外はより簡単に思えます。
以下を試すことができます:
find ./ ! \( -path ./tmp -prune \) ! \( -path ./scripts -prune \) -type f -name '*_peaks.bed'
_peaks.bed
。