find et négation d'une condition

J'essaie de find tous les files qui ont 'pillar' dans le nom (case incentive) et ne contiennent pas 'cache' (aussi insensible à la casse) avec

find . -iname '*pillar*' -and -not -iname '*cache*' 

mais cela ne fonctionne pas comme je trouve (entre autres)

 ./Caches/Metadata/Safari/History/https:%2F%2Fwww.google.ch%2Fsearch?q=pillars+of+eternity+dropbox&client=safari&rls=en&biw=1440&bih=726&ei=CnBDVbhXxulSnLaBwAk&start=10&sa=N%23.webhistory 

Qu'est-ce que je fais mal?

Il semble que vous voulez éviter de chercher des files dans les directorys *cache* plus que de find des files avec *pillar* et non *cache* dans leur nom. Ensuite, dites simplement de ne pas déranger la descente dans *cache* directorys *cache* :

 find . -iname '*cache*' -prune -o -iname '*pillar*' -print 

Ou avec zsh -o extendedglob :

 ls -ld -- (#i)(^*cache*/)#*pillar* 

(pas ssortingctement équivalent car cela signalerait un file foo/pillar-cache )

Ou (less efficace car il descend tout l'tree comme dans la solution de @ apaul ):

 ls -ld -- (#i)**/*pillar*~*cache* 

Détails sur les zsh spécifiques à zsh :

  • (#i) : activer l'appariement insensible à la casse
  • ^ : opérateur de négation glob
  • (...) : regroupement (comme @(...) dans ksh ).
  • <something># : zéro ou plus de <something> (comme * en regexps).
  • Opérateur ~ : and-not (correspond à l'set du path)
  • **/ : 0 ou plusieurs niveaux de directorys (abréviation de (*/)# ).

Ajoutez le qualificatif (D) glob si vous voulez descendre dans les dires cachés et faire correspondre les files cachés comme dans la solution de find .

Les options de find vous avez spécifiées s'appliquent au nom de file et non au nom des sous-directorys.

Ici, votre nom de file ne contient pas de cache mais contient le pillar , donc il correspond.

Dans votre cas, vous souhaiterez peut-être utiliser l'option -path . Quelque chose comme:

 find . -iname '*pillar*' -and -not -ipath '*cache*'