web-dev-qa-db-ja.com

検索:任意のレベルに存在するn個の異なるディレクトリとm個の異なるファイルを除外しますが、除外されたディレクトリからいくつかのファイルを含めます

パス内のすべてのディレクトリとファイルを再帰的に検索したいが、特定のパターンに一致する他のいくつかのディレクトリとファイルを除外したい。次に、検索結果に対してさらにコマンドを実行したいと思います。たとえば、cpmvrsync、またはrmfindの結果です。

node_modules.gitbuildディレクトリ全体、およびenhancersディレクトリ全体をプルーニングしたいが、検索結果に-namexyz.jsのファイルを含めたいとします。 enhancersディレクトリ。

以下のコマンドを使用すると、検索結果にxyz.jsファイルを含めることを除いて、目的の結果を得ることができます。コマンドは非常に長いです。

find . -path "./node_modules" -Prune -o -path "./.git*" -Prune -o -path "./build" -Prune -o -path "*/enhancers" -Prune -o -print | grep 'xyz.js'

--root
  |--node_modules
  |--public
  |--build
  |--.git
  |--.gitignore
  |--.env
  |--package.json
  |--src
    |--history
    |--store
      |--middleware
        |..
        |..
          |--enhancers
            |..
              |--xyz.js

上記の概略ディレクトリ構造では、|..はディレクトリ内の不明な深さ(レベル)を表します。

示されているディレクトリ構造で、以下を除くすべてのファイルを検索結果に含めたい

  • node_modulesディレクトリ全体
  • .gitディレクトリ全体
  • .gitignoreファイル
  • enhancersディレクトリ全体ですが、検索結果にxyz.jsファイルを含めます

それを行うためのより短い方法はありますか?主な混乱は、正規表現とグロブのパターンの間です。

./.git*./\.git*に置き換えると、それも機能します。

*で複数の*/enhancersを使用する場合も、機能します。

findコマンドで適用できるファイルとディレクトリの検索パターンルールは何ですか?

1

enhancers内のファイルを見つけたい場合は、Pruneできません。 Pruneは、findがまったく下降しないことを意味するため、そこにファイルが見つかる可能性はありません。ここでは、それらをプルーニングするのではなく、それらの下にあるxyz.jsファイル以外のファイルを除外する必要があります。

そう:

find . \( \
          -path ./node_modules -o \
          -path './.git*' -o \
          -path ./build \
       \) -Prune -o \( \
          ! -path '*/enhancers' ! -path '*/enhancers/*' -o \
          -name xyz.js \
       \) -print

ここでは読みやすさのためにいくつかの行にあります。

これらのファイルで何かをしたい場合は、-print-exec sh -c 'for file do something with "$file"; done' sh {} +に置き換えてください。

または、出力を後処理する場合は、-print0を使用し、grep/xargs/cut/sort-z/--null/-0オプションを使用します。 (GNU実装または互換性があると仮定))NULで区切られた入力で動作します。

1

フィルタルールを使用して2つのrsyncコマンドラインでbashシェルスクリプトを作成できます。

#!/bin/bash

rsync -Havn \
 --filter="- target" \
 --filter="- node_modules" \
 --filter="- .git" \
 --filter="- build" \
 --filter="- enhancers" \
 ./ target

rsync -Havn  \
 --filter="+ xyz.js" \
 --filter="+ */" \
 --filter="- *" \
 src target

-nでNice出力が生成されるまで、このシェルスクリプトを編集するのはかなり簡単です。これは、「ドライラン」が意図を示すだけであることを意味します。

問題がなければ、2つのコマンドラインから-nを削除して、rsyncに処理を任せることができます。あるいは、テキスト出力に満足していて、それをファイルに保存するか、何らかの方法で他のコマンドにパイプする(rsyncコピー以外のことを行うため)かもしれません。

0
sudodus