Creo que una vez usaste -or
operador, entonces debe mantenerlo consistente para evitar un orden ambiguo de las operaciones lógicas cuando tiene múltiples condiciones conectadas usando OR lógico.
Parece el -exec
parte se agrupa junto con el segundo -name "*.h"
.
Entonces, para que funcione correctamente, debe agregar los corchetes de la siguiente manera:
find . '(' -name '*.cpp' -o -name '*.h' ')' -exec echo {} ';'
Alternativamente, combine algunas extensiones en una usando -regex
:
find . ! -regex ".*\.\(cpp\|h\)" -exec echo {} \;
Ninguno de los dos. Es la sintaxis de las opciones lo que es "incorrecto". find
evalúa secuencialmente. Por lo tanto, evalúa la primera expresión (-name "*.cpp"
) luego encuentra un -o
bandera. Si la primera expresión es verdadera, find
no seguirá evaluando el segundo (-name "*.h" -exec echo {} \;
), en cambio no hace nada. Verás, toda la parte después de -o
es una expresión. Por lo tanto, esto solo se ejecuta para los archivos que coinciden con la segunda expresión. Por eso solo ves el 1.h
archivo, que pasa sólo la segunda expresión. Consulte la página de manual de búsqueda:
expr1 -o expr2
Or; expr2 is not evaluated if expr1 is true.
¿Por qué es útil? Considere lo siguiente:
find /path -exec test_file_for_something {} -print \; -o -name "xyz" -exec ls -l {} \;
En esta declaración de búsqueda, el archivo se entrega a test_file_for_something
como parámetro. Ahora, dependiendo del código de retorno de los comandos, la primera expresión es verdadera (entonces -print
se ejecuta y termina allí) o falso (entonces la segunda expresión después del -o
se evalúa la bandera). Y si eso es cierto (el nombre es xyz
), luego -exec
se ejecuta.
Para su problema, puede usar esto para agrupar los elementos como una expresión :
find . \( -name "*.cpp" -o -name "*.h" \) -exec echo {} \;