正規表現に一致するベース名を持つファイルを検索したい。私はこれを試しました:
$ find '/my/path' -regextype posix-extended -regex 'reg1' -regex 'reg2'
私の問題は、正規表現がフルパスに対してテストされていることです。ファイルのベース名のみをテストしたいのですが。
GNU find には、ベース名のみに適用される正規表現演算子は含まれていません。これは残念です。最も近いのは、正規表現を変更して、正規表現の先頭からスラッシュで区切られた部分を削除することです。
find /my/path -regextype posix-extended -regex ".*/reg1"
これは通常の Linux パス名では機能しますが、通常とは異なる文字 (改行など) を含むパス名では失敗する可能性があります。
geekosaur が指摘するように、入力正規表現は複数のコンポーネントに一致するべきではありません。正規表現を制御できない場合 (たとえば、変数 $REG1 として渡された場合)、マングリングして次のように変換でき.
ます[^/]
。
find /my/path -regextype posix-extended -regex ".*/${REG1/./[^/]}"
これは多くの正規表現で失敗します (たとえば、'.*.txt' はひどく壊れます)。ただし、正規表現が単純になることがわかっている場合は、うまくいく可能性があります。
-exec
遅いが機能する解決策として、ブロック内ですべてのパターン マッチングを行うことができます。
find /my/path -exec bash -c 'basename "$0" | egrep -q '"'$REG1'"' && echo "$0"' '{}' ';'
ここでのロジックは、find
すべてのファイルを列挙し、それらを$0
サブシェルに割り当てるというものです。サブシェルはbasename
andを使用egrep
して、入力正規表現に一致するパスに出力をフィルタリングします。egrep はローカル マッチを見つけることに注意してください。完全なベース名に一致させたい場合は、使用しますegrep -q '"'^$REG1\$'"'
入力正規表現のセマンティクスに応じて (たとえば$REG1
、ベース名の任意の部分文字列と一致することを意図している場合)、最初にパス全体で正規表現を検索し、次にベース名のみにフィルター処理することで、パフォーマンスを向上させることができます。
find /my/path -regextype posix-extended -regex ".*${REG1}.*" \
-exec bash -c 'basename "$0" | egrep -q '"'$REG1'"' && echo "$0"' '{}' ';'
次のようなもので、正規表現を固定する必要があります
find /my/path -regextype posix-extended -regex 'mumble$'
whereは、文字mumble
を除外する方法で記述する必要があります/
(たとえば、 を使用できない場合は.*
、 と言う必要があります[^/]*
)。