このようなフォルダ構造があります。
.
└── apps/
├── bo/
│ └── platform/
│ └── values-dev.yaml
├── canary/
│ └── platform/
│ └── values-canary-dev.yaml
├── foo/
│ ├── customer
│ ├── audit
│ ├── platform/
│ │ └── values-foo-dev.yaml
│ └── platform-gb/
│ └── values-foo-dev.yaml
└── bar/
├── customer
├── audit
├── platform/
│ └── values-bar-dev.yaml
├── platform-usa/
│ └── values-bar-dev.yaml
├── platform-ca/
│ └── values-bar-dev.yaml
└── platform-ie/
└── values-bar-dev.yaml
表現についてあらかじめごめんなさい。
以下を使用して、各ファイル内の特定の文字列を見つけbash
て置き換えようとします。puppy
values-*-dev.yaml
しかし、foo
各サブディレクトリとbar
各サブディレクトリのファイルを変更して、platform
次のdog
ように置き換えたいと思います。dog
私が得た最も近いものは次のとおりです。ここには内部ファイルだけがリストされていますが、foo
生涯にわたってそれを把握することはできません。
find . -type f -path '*foo/platform*' -name 'values-*-dev.yaml'
foo
括弧で囲んで追加すると効果があると思いましたがbar
そうではありませんね。
find . -type f -path '*(foo|bar)/platform*' -name 'values-*-dev.yaml'
答え1
いいえ、find
'-name
と-path
デフォルトのshワイルドカードパターンのみがサポートされているため、?
範囲/セット/クラスの文字数と単一文字(およびエスケープ)で機能する単一文字のみがサポートされます。*
[...]
\
ここでは、標準を使用してfind
次のことを行います。
find . '(' -path '*/foo/platform*' -o -path '*/bar/platform*' ')' \
-name 'values-*-dev.yaml' \
-type f \
-exec perl -pi -e 's/puppy/dog/g' {} +
一部のfind
実装では、-regex
正規表現を使用してフルパスに一致する述語をサポートします。 ~のため拡大するregexps、BSDでは、「オプション述語」として知られている-E
grep / sedおよびGNUに似たオプションを使用できます。find
-regextype posix-extended
すべての変形に対して正規表現は暗黙的に固定されるため、次のものが必要です。
# BSD
find -E . -regex '.*/(foo|bar)/platform.*' \
-name 'values-*-dev.yaml' \
-type f \
-exec perl -pi -e 's/puppy/dog/g' {} +
# GNU
find . -regextype posix-extended \
-regex '.*/(foo|bar)/platform.*' \
-name 'values-*-dev.yaml' \
-type f \
-exec perl -pi -e 's/puppy/dog/g' {} +
zsh
または、次のように使用できます。
perl -pi -e 's/puppy/dog/g' -- **/(foo|bar)/platform*/**/values-*-dev.yaml(.)
zshには、次のような基本的なshに基づくいくつかの便利なglobモード拡張があります。
**/
すべてのレベルのサブディレクトリと一致(a|b)
: 拡張正規表現に似ています。- ここに含まれるglob修飾子は、
.
検索を次に制限するために使用されます。定期的なファイル(find
sと同じ-type f
)