同じ CWD 内の正規表現で動作するが、別のディレクトリからは動作しない検索

同じ CWD 内の正規表現で動作するが、別のディレクトリからは動作しない検索

find コマンドがあり、現在の作業ディレクトリの$directoryドットの代わりに変数を使用して任意のディレクトリから発行したいと考えています。.

何が効くのか

  • 例1
find $directory -maxdepth 1 -type d -name "test*"

それでいくつかの結果が得られます。

これも有効です

  • 例2
find . -maxdepth 1 -type d -regextype posix-extended -regex "^./[a-zA-Z0-9]+([-_]?[a-zA-Z0-9]+)*-[0-9]{1,3}(.[0-9]{1,3}){,3}\$"

ただし、 では$directory機能しません。./正規表現の先頭の を削除したことに注意してください。

  • 例3
find $directory -maxdepth 1 -type d -regextype posix-extended -regex "^[a-zA-Z0-9]+([-_]?[a-zA-Z0-9]+)*-[0-9]{1,3}(.[0-9]{1,3}){,3}\$"

どうしてこんなことに?

ありがとう

答え1

-regex(標準ではありません) は、標準と同様に、-pathファイルの完全なパスに一致します。これらのパスは の内容で始まり、$directoryによって見つかったディレクトリとファイルが続きますfind。したがって、$directoryが の場合、は に対して正規表現と一致しますが、最初の文字が であり、数字ではないため、ここでは一致しません。/some/dir-regex/some/dir/file-discovered-by-find/

最初のケースでは、があったため、正規表現は (は正規表現演算子であるため、または GNUので暗示されているように であるべき^./でした)で始まりました。^\./.\./^find-regex$directory.

でも同様のことを行う必要がありますが、 ( ...)$directory内のすべての正規表現演算子をエスケープする必要があることに注意してください。ただし、ここでは次のようにすることもできます。$directory^$*()+[]?.\

find "$directory" -maxdepth 1 -type d -regextype posix-extended \
  -regex '.*/[[:alnum:]]+([-_][[:alnum:]]+)*-[[:digit:]]{1,3}(\.[[:digit:]]{1,3}){0,3}'

(また、任意の文字ではなくリテラルに一致させたいと考えていると思われるため、.を に置き換え、ここでは必要のない を削除しました)。\..?

つまり、パターン (ここでは を含まないことが保証されています/) を、 に一致する何かの後ではなく、 のいずれか/(および暗示されているようにファイル パスの最後まで$) の後と一致させます$directory

を使用するとzsh -o extendglob、次のことができます。

set -o extendedglob
w=[0-9a-zA-Z] d=[0-9]
print -rC1 -- $directory/$~w##([-_]$~w##)#-$~d(#c1,3)(.$~d(#c1,3))(#c0,3)(#q/)

これには、GNU のfindものに比べていくつかの利点があります。

  • GNU以外のシステムでも動作します(GNUへの依存がなくなりますfind
  • $directoryで始まっても動作します-
  • 並べ替えられたリストを表示します
  • ではzsh[a-zA-Z0-9]一致するものはランダムではなく、 や のようにロケールによって変化しません。 は、find一致させたい文字と推定されるものだけに一致します。 ではfind、同等のものを取得する必要があります[abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789]
  • $directoryディレクトリへのシンボリックリンクであっても機能します(ただし、そのため-Hにはオプションを追加できますfind)。
  • ファイル パス (この場合は の内容$directory) に、現在のロケールで有効な文字を形成しないバイト シーケンスが含まれている場合でも機能します (の は有効な文字にのみ一致するため、findの は-regexそれら.*に一致できません.)。
  • リストを印刷する代わりに、それを直接使用することができます (コマンドの引数として、ループするなど)
  • (<0-255>~????*)また、0 から 255 までの 3 桁以下の 10 進数や(<0-255>~0?*)先頭に 0 が付かない数値を一致させるためにも使用できます。globszshは、数値の範囲の一致をサポートする数少ないパターン マッチング API の 1 つです。

関連情報