Obtener la opción -exec en find para trabajar

Estoy tratando de hacer que find imprima una list de directorys que contienen files que no sean jpg, pero creo que mi uso de la opción -exec está roto. Mi entorno es Cygwin Bash.

 $ find ! -iname "*.JPG$" -exec dirname find: missing argument to `-exec' 
 $ find ! -iname "*.JPG$" -exec dirname {} find: missing argument to `-exec' 
 $ find ! -iname "*.JPG$" -exec dirname; find: missing argument to `-exec' 
 $ find ! -iname "*.JPG$" -exec dirname ; find: missing argument to `-exec' 
 $ find ! -iname "*.JPG$" -exec dirname {}; find: missing argument to `-exec' 

A -exec necesita ser terminado con a ; o a + . El ; hace que el command se ejecute una vez por cada nombre de file encontrado, mientras que + hace que el command se ejecute una vez para todos los nombres de file.

Aquí hay un ejemplo de trabajo:

 find ! -iname "*.JPG" -exec dirname {} \; 

Algunas diferencias notables de tus bashs:

  1. Debe haber un espacio entre {} y \;
  2. El ; debe ser escapado, porque es un metacarácter de shell.
  3. Como @muru señaló en su respuesta, " -iname tomo un glob, no un regex"

Tratar:

 find -type f ! -iname "*.JPG" -exec dirname {} \; | sort -u 

Notas;

  • Para completar el command -exec , se necesita {} para mostrar dónde debe ir el nombre de file y se necesita un punto y coma. Debido a que el caparazón comería un punto y coma simple, tenemos que escaping para que se pase a find .

  • -iname combina globs, no expresiones regulares. Entonces, el último $ en "*.JPG$" probablemente no sea lo que quieres.

  • Dijiste que quieres una "list de directorys que contienen files que no sean jpgs". En consecuencia, agregué -type f para que estuviéramos seguros de que solo miramos los directorys que contienen al less un file.

  • Los resultados se sort -u para eliminar duplicates.

La syntax

 -exec [command] ... {} ... ; -exec [command] ... {} ... + 

Como ; es parte de la syntax de shell, necesita escaping de modo que find vea como un argumento:

 find .. -exec dirname {} \; 

Por cierto, -iname no usa expresiones regulares- solo usa *.jpg sin $ .


Ahora me sorprende que con GNU find no necesitemos usar dirname en absoluto. En lugar:

 find ... -printf "%h\n"