これができる 1 つの方法です...
find . -type f -name "*_peaks.bed" | egrep -v "^(./tmp/|./scripts/)"
私にとって、この解決策は 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
で指定する方法は次のとおりです。 :
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 \( -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 find マニュアル:
-path pattern
[...]
To ignore a whole
directory tree, use -prune rather than checking
every file in the tree.
確かに、 -not -path "./pathname"
を使用すると ,find は "./pathname"
の下の各ノードの式を評価します .
find 式は単なる条件評価です。
\( \)
- グループ操作 (-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
どのパスがチェックされているかを確認します。