Penso che una volta hai usato -or
operatore, devi mantenerlo coerente per evitare un ordine ambiguo delle operazioni logiche quando hai più condizioni connesse utilizzando l'OR logico.
Sembra il -exec
la parte è raggruppata insieme alla seconda -name "*.h"
.
Quindi, per farlo funzionare correttamente, devi aggiungere le parentesi come di seguito:
find . '(' -name '*.cpp' -o -name '*.h' ')' -exec echo {} ';'
In alternativa, combina alcune estensioni in una sola utilizzando -regex
:
find . ! -regex ".*\.\(cpp\|h\)" -exec echo {} \;
Né. È la sintassi delle opzioni che è "sbagliata". find
valuta sequenzialmente. Pertanto, valuta la prima espressione (-name "*.cpp"
) incontra quindi un -o
bandiera. Se la prima espressione è vera, find
non continuerà a valutare il secondo (-name "*.h" -exec echo {} \;
), invece non fa nulla. Vedi, l'intera parte dopo -o
è un'espressione. Pertanto, questo viene eseguito solo per i file che corrispondono alla seconda espressione. Ecco perché vedi solo 1.h
file, che passa solo la seconda espressione. Vedi la pagina man di find:
expr1 -o expr2
Or; expr2 is not evaluated if expr1 is true.
Perché è utile? Considera quanto segue:
find /path -exec test_file_for_something {} -print \; -o -name "xyz" -exec ls -l {} \;
In questa istruzione find il file viene assegnato a test_file_for_something
come parametro. Ora, a seconda del codice restituito dai comandi, la prima espressione è vera (quindi -print
viene eseguito e finisce lì) o false (quindi la seconda espressione dopo il -o
flag viene valutato). E se quello è vero (il nome è xyz
), quindi -exec
viene eseguito.
Per il tuo problema puoi invece utilizzare this per raggruppare gli elementi insieme come un'unica espressione :
find . \( -name "*.cpp" -o -name "*.h" \) -exec echo {} \;