Ich glaube, Sie haben einmal -or verwendet Operator, dann müssen Sie ihn konsistent halten, um eine mehrdeutige Reihenfolge logischer Operationen zu vermeiden, wenn Sie mehrere Bedingungen haben, die mit logischem ODER verbunden sind.
 Es scheint die -exec Teil wird zusammen mit dem zweiten -name "*.h" gruppiert .
Damit es richtig funktioniert, müssen Sie die Klammern wie folgt hinzufügen:
find . '(' -name '*.cpp' -o -name '*.h' ')' -exec echo {} ';'
 Kombinieren Sie alternativ mehrere Erweiterungen zu einer, indem Sie -regex verwenden :
find . ! -regex ".*\.\(cpp\|h\)" -exec echo {} \;
 Weder. Es ist die Syntax der Optionen, die "falsch" ist. find wertet nacheinander aus. Daher wertet es den ersten Ausdruck aus (-name "*.cpp" ) trifft dann auf einen -o Flagge. Wenn der erste Ausdruck wahr ist, find wird die zweite nicht weiter auswerten (-name "*.h" -exec echo {} \; ), tut stattdessen nichts. Sie sehen, der ganze Teil nach -o ist ein Ausdruck. Daher wird dies nur für Dateien ausgeführt, die dem zweiten Ausdruck entsprechen. Deshalb sehen Sie nur die 1.h Datei, die nur den zweiten Ausdruck übergibt. Siehe Find-Manpage:
   expr1 -o expr2
          Or; expr2 is not evaluated if expr1 is true.
Warum ist das nützlich? Beachten Sie Folgendes:
find /path -exec test_file_for_something {} -print \; -o -name "xyz" -exec ls -l {} \;
 In dieser find-Anweisung wird die Datei an test_file_for_something übergeben als Parameter. Abhängig vom Rückgabecode des Befehls ist nun der erste Ausdruck wahr (dann -print ausgeführt wird und dort endet) oder false (dann der zweite Ausdruck nach dem -o Flag wird ausgewertet). Und wenn das wahr ist (der Name ist xyz ), dann -exec wird ausgeführt.
Für Ihr Problem können Sie dies stattdessen verwenden, um die Elemente zu einem Ausdruck zusammenzufassen :
find . \( -name "*.cpp" -o -name "*.h" \) -exec echo {} \;