Fazendo com que a opção -exec no find funcione

Fazendo com que a opção -exec no find funcione

Estou tentando imprimir finduma lista de diretórios que contêm arquivos diferentes de imagens jpg, mas acho que meu uso da -execopção está quebrado. Meu ambiente é 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'

Responder1

A -execprecisa ser finalizado com a ;ou a +. Isso ;faz com que o comando seja executado uma vez por nome de arquivo encontrado, enquanto +faz com que o comando seja executado uma vez para todos os nomes de arquivo.

Aqui está um exemplo prático:

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

Algumas diferenças notáveis ​​em relação às suas tentativas:

  1. Deve haver um espaço entre {}e\;
  2. Deve ;ser escapado, porque é um metacaractere do shell.
  3. Como @muru apontou em sua resposta, -inameé necessário um glob, não um regex

Responder2

Tentar:

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

Notas;

  • Para completar o -execcomando, {}é necessário um para mostrar onde o nome do arquivo deve ireé necessário um ponto e vírgula. Como o shell comeria um ponto-e-vírgula simples, temos que escapar dele para que seja passado para find.

  • -inamecorresponde a globs, não a expressões regulares. Portanto, a $entrada final "*.JPG$"provavelmente não é o que você deseja.

  • Você disse que deseja uma "lista de diretórios que contenham arquivos diferentes de jpgs". Conseqüentemente, adicionei -type fpara que tivéssemos certeza de que olharíamos apenas os diretórios que contêm pelo menos um arquivo.

  • Os resultados são enviados sort -upara remover duplicatas.

Responder3

A sintaxe:

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

Como ;faz parte da sintaxe do shell, você precisa escapar dela para que findseja visto como um argumento:

find .. -exec dirname {} \;

A propósito, -inamenão usa expressões regulares - basta usar *.jpgsem a extensão $.


Agora me ocorre que com o GNU find não precisamos usar dirnamenada. Em vez de:

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

informação relacionada