Encuentre trabajar con expresiones regulares en el mismo CWD pero no desde otro directorio

Encuentre trabajar con expresiones regulares en el mismo CWD pero no desde otro directorio

Tengo un comando de búsqueda y me gustaría emitirlo desde un directorio arbitrario con una $directoryvariable en lugar del punto .para el directorio de trabajo actual.

lo que funciona es esto

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

Eso me da algunos resultados.

También esto funciona

  • Ejemplo 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}\$"

Sin embargo, con $directorya no funciona. Tenga en cuenta que eliminé el ./al comienzo de la expresión regular.

  • Ejemplo 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}\$"

¿Por qué es así?

Gracias

Respuesta1

-regex(no estándar), al igual que las -pathcoincidencias estándar en la ruta completa de los archivos. Esas rutas comienzan con el contenido de $directoryseguido de los directorios y archivos encontrados por find. Entonces, si $directoryes /some/dir, -regexcoincidirá con la expresión regular /some/dir/file-discovered-by-findy nunca coincidirá aquí, ya que el primer carácter es un /, no un alnum.

En el primer caso, su expresión regular comenzó con ^./(debería haber sido ^\./como .es un operador de expresión regular, o simplemente \./como ^está implícito en GNU find) -regexcomo $directoryestaba ..

Tendrías que hacer algo similar con $directory, teniendo en cuenta que todos los operadores de expresiones regulares en $directory( ^$*()+[]?.\...) deberían tener escape. Pero aquí también podrías hacerlo:

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

(También lo reemplacé .con, \.ya que sospecho que desea hacer coincidir un carácter literal .y no cualquier carácter, y eliminé el ?que no era necesario aquí).

Es decir, haga que su patrón (que aquí se garantiza que no abarcará un /) coincida después de cualquier /(y hasta el final de la ruta del archivo, como $también está implícito) en lugar de después de algo que coincida $directory.

Con zsh -o extendglob, puedes hacer:

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/)

El cual tiene varias ventajas sobre el de GNU find:

  • Funcionaría incluso en sistemas que no sean GNU (elimina la dependencia de GNU find)
  • funciona incluso si $directorycomienza con-
  • te da una lista ordenada
  • en zsh, lo que [a-zA-Z0-9]coincide no es aleatorio y no varía con las configuraciones regionales como en findy coincide con los caracteres. Supongo que desea que coincidan y solo ellos. En find, necesitarías [abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789]obtener el equivalente.
  • Funciona incluso si $directoryes un enlace simbólico a un directorio (aunque puedes agregar la -Hopción findpara eso).
  • Funciona incluso si las rutas de archivo (en este caso, el contenido de $directory) contienen una secuencia de bytes que no forman caracteres válidos en la configuración regional actual ( find's -regex' .*no pueden coincidir con ellos porque .solo coincide con caracteres válidos).
  • en lugar de imprimir esa lista, puede usarla directamente (como argumentos para un comando, para recorrerlo, etc.)
  • También puede usar cosas como (<0-255>~????*)hacer coincidir números decimales del 0 al 255 compuestos por no más de 3 dígitos o (<0-255>~0?*)para aquellos números sin 0 inicial, zshsiendo los globos una de las pocas API de coincidencia de patrones que admiten rangos de números coincidentes.

información relacionada