パス内のすべてのディレクトリとファイルを再帰的に検索したいが、特定のパターンに一致する他のいくつかのディレクトリとファイルを除外したいと思います。その後、検索結果、おそらく、またはcp
のmv
結果rsync
に対してrm
追加のコマンドを実行しようとしますfind
。
ディレクトリ全体を整理し、ディレクトリを整理したいのですが、node_modules
ディレクトリ.git
内の不明な深さに存在する-nameを持つファイルを検索結果に含めたいとしますbuild
。enhancers
xyz.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 {} +
または、出力を後処理するには、NULで区切られた入力を処理できるように//-print0
オプション-z
(GNU実装または互換性を想定)を使用します。--null
-0
grep
xargs
cut
sort
答え2
rsync
フィルタルールを含む2つのコマンドラインを使用して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
つまり、「模擬実行」では、その意図のみが表示されます。
状況が正しいと判断した場合は、-n
両方のコマンドラインを削除してそのままにしてくださいrsync
。あるいは、テキスト出力に満足してファイルに保存したり、他のコマンドにパイプしたりすることもできます(rsyncコピー以外の操作を実行するため)。