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 {} \;