GNU/Linux >> Linux の 問題 >  >> Linux

find コマンドを使用するが、2 つのディレクトリ内のファイルを除外する

これができる 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 ffindに指定 結果にファイルのみが必要であること
  • -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 どのパスがチェックされているかを確認します。


Linux
  1. findコマンドを使用してLinux上のファイルとディレクトリを検索します

  2. find でディレクトリを除外する方法。指図

  3. パターンに一致するファイルを削除するために find コマンドを使用する方法は?

  1. Linuxでトップディレクトリとファイル(ディスク容量)を見つける方法

  2. Grepコマンドを使用してファイル内のテキストを検索する方法

  3. Linuxでファイルとディレクトリをコピーする

  1. 最大のファイルまたはディレクトリを見つけますか?

  2. Unix検索コマンドからディレクトリのリストを除外しますか?

  3. Linux の find コマンドを使用してファイルを検索する方法