# Recherche récursive de contenu de fichiers



## SuperCed (18 Avril 2006)

Je cherche à effectuer une recherche dans un répertoires et dans tous les répertoires contenus dans celui-ci, ceci de manière récursive.
Je voudrais chercher une chaîne dans le contenus des fichiers.

Comment faire ça avec le shell? Sinon, avec Spotlight?
Comment lance-t-on à la main l'indexation spotlight?

Merci!


----------



## FjRond (18 Avril 2006)

```
% grep -r liberté . 2>/dev/null                         19:09
./.backup/guerre.tex~:Si deux hommes désirent la même chose alors qu'il n'est pas possible qu'ils en jouissent tous les deux, ils deviennent ennemis: et dans leur poursuite de cette fin (qui est, principalement, leur propre conservation, mais parfois seulement leur agrément), chacun s'efforce de détruire ou de dominer l'autre. Et de là vient que, là où l'agresseur n'a rien de plus à craindre que la puissance individuelle d'un autre homme, on peut s'attendre avec vraisemblance, si quelqu'un plante, sème, bâtit, ou occupe un emplacement commode, à ce que d'autres arrivent tout équipés, ayant uni leurs forces, pour le déposséder et lui enlever non seulement le fruit de son travail, mais aussi la vie ou la liberté. Et l'agresseur à son tour court le même risque à l'égard d'un nouvel agresseur.
./.backup/prop3_8.txt~:ait donné à l'homme la raison et la liberté du  vouloir  qui  se  fonde  sur
./.backup/prop3_8.txt~:attenter à la liberté civile  sans  porter  par  là  préjudice  à  tous  les
./.backup/prop3_8.txt~:extérieures. Mais cette liberté s'étend peu  à  peu.  Quand  on  empêche  le
./.backup/prop3_8.txt~:pourvu qu'ils puissent coexister avec la liberté  d'autrui,  on  entrave  le
.../...
```
L'option _r_ pour la recherche récursive; on peut bien sûr utiliser une expression rationnelle à la place du mot, un répertoire au lieu du répertoire courant désigner par le « . ». 
2>/dev/null évite les messages d'erreur pour la recherche dans les fichiers non autorisés.


----------



## olof (18 Avril 2006)

Ou quelque chose comme ça :

find . -exec grep -i "pattern" {} \;


----------



## FjRond (18 Avril 2006)

olof a dit:
			
		

> Ou quelque chose comme ça :
> 
> find . -exec grep -i "pattern" {} \;


Oui, mais la sortie est moins sélective. En partant du même répertoire, j'obtiens des pages entières de texte. 
D'autre part, il faut ajouter ici aussi le : 2>/dev/null pour éviter d'encombrer l'écran avec ce genre de chose:

```
grep: ./Travail/Langage/proslogionIV.tex: No such file or directory
grep: ./Travail/manuel/.iTeXMac/bin: No such file or directory
grep: ./Travail/manuel/.iTeXMac/BuiltIn/bin: No such file or directory
grep: ./Travail/manuel/.iTeXMac/Local/bin: No such file or directory
grep: ./Travail/manuel/.iTeXMac/Network/bin: No such file or directory
grep: ./Travail/manuel/methodissert/.iTeXMac/bin: No such file or directory
grep: ./Travail/manuel/methodissert/.iTeXMac/BuiltIn/bin: No such file or directory
grep: ./Travail/manuel/methodissert/.iTeXMac/Local/bin: No such file or directory
grep: ./Travail/manuel/methodissert/.iTeXMac/Network/bin: No such file or directory
```
Bref, je trouve la sortie de ma commande plus directe et claire. Et pourtant, je suis un grand utilisateur de find que j'apprécie tant que je n'ai même pas cherché à savoir ce que fait Spotlight.


----------



## bompi (19 Avril 2006)

On peut aussi noter que le _grep_ direct sera bien plus rapide si le nombre de fichiers est élevé, _find_ devenant un peu lourd (il exécute la commande _grep_ à chaque trouvaille).
Par exemple, si l'on souhaite faire ce genre de requête sur les sources de XNU, j'opte pour la solution de FJRond 

En passant : les gens de WebGlimpse proposent gratuitement un grep particulier permettant une erreur de _n_ caractères dans la recherche. Par exemple, en cherchant avec *agrep* la chaîne "brol" avec une erreur possible, "crol", "brul" conviennent mais "crul" ne convient pas. L'intérêt ? Lorsque l'on n'est pas sûr de l'orthographe (ou du goût pour l'orthographe des auteurs des documents à parcourir ...) Cette fois-ci, c'est à utiliser avec _find_ car il n'y a pas de récursivité.
*agrep* peut s'installer avec DarwinPorts.


----------



## SuperCed (19 Avril 2006)

Merci c'est ce que je cherchais.
Existe-il un moyen de lancer l'indexation Spotlight via le terminal?


----------



## olof (19 Avril 2006)

SuperCed a dit:
			
		

> Merci c'est ce que je cherchais.
> Existe-il un moyen de lancer l'indexation Spotlight via le terminal?



J'ai pas lu, mais tu devrais trouver ton bonheur ici : http://www.macworld.com/2005/07/secrets/augustgeekfactor/index.php


----------



## bompi (19 Avril 2006)

Les commandes de Terminal pour gérer l'indexation, les index et la recherche avec SpotLight sont : mdcheckschema, mdfind, mdutil, mdimport et mdls.
Toutes disposent d'une page de manuel.


----------



## FjRond (19 Avril 2006)

On peut encore utiliser find avec xargs, mais seulement dans un répertoire dans lequel les noms de fichiers et de sous-répertoires ne contiennent pas d'espaces :

```
% find /sw/etc -iname "*.conf" | xargs grep -i "trees"   
/sw/etc/fink.conf:Trees: local/main stable/main stable/crypto local/bootstrap unstable/main unstable/crypto
```
Sinon, voici un petit script que je me suis fait pour la recherche dans mon répertoire personnel:

```
#!/bin/sh
# recherche -- permet de chercher un mot ou une expression 
# dans un fichier du répertoire courant de manière récursive.

F="$1"
EXP="$2"

if [ $# -lt 2 ]; then
    cat <<EOF
SYNTAXE : recherche ['fichier'] ['expression']
EOF
    exit 1
else 
    find . -name "$F" -exec grep -i "$EXP" {} \; -print 2>/dev/null
fi

exit 0
```
Exemples d'utilisations :

```
% recherche '*.txt'    
SYNTAXE : recherche ['fichier'] ['expression']
 % recherche '*.txt' 'LaTeX'    
 % recherche '*.tex' 'LaTeX' 
%%% mode: latex
./env_ex2.tex
%%% mode: latex
./gris_col.tex
%%% mode: latex
./PGFManuel/pgfman.tex
%%% mode: latex
./TeXnique/bonjour.tex
%%% mode: latex
./TeXnique/guillemets.tex
%%% mode: latex
./TeXnique/lr_qq.tex
```


----------



## parasite (21 Avril 2006)

FjRond a dit:
			
		

> voici un petit script que je me suis fait pour la recherche dans mon répertoire personnel:
> 
> ```
> #!/bin/sh
> ...


ou plus simplement :

```
#!/bin/sh
[ $# -lt 2 ] && echo "SYNTAXE : recherche 'motif:nom' 'motif:expression'" && exit 1
2>/dev/null find . -name "$1" -exec grep -i "$2" {} \; -print
```
note: si tu mets entre crochets des arguments dans le synopsis, c'est qu'ils ne sont pas nécessaires, ce qui est faux ici

dernière ligne qu'on pourrait remplacer par :
mdfind -0 -onlyin "$PWD" "kMDItemFSName == '*"$1"*'cd" | xargs -0 grep -i "$2"
autant laisser la redirection d'erreur à faire si besoin explicitement à l'appel


sinon, une approche plus simpliste, en bash, permettant de faire seulement une recherche sur le contenu dans le répertoire courant (en gros, en fait un genre de grep -r -e arg1 ... -e argn . mais à base de Spotlight) :

```
function mdflc {

    function les_args { ## avec [ $# -gt 0 ]
	for (( i=1; i<$#; i++ )); do
	    echo -n "kMDItemTextContent == '$(eval echo \${$i})'cd && "
	done
	echo "kMDItemTextContent == '$(eval echo \${$#})'cd"
    }

    function les_args_rec { ## au choix :-p
        echo -n "kMDItemTextContent == '"$1"'cd "
        shift && echo -n "&& " && les_args_rec "$@"
    }

    if [ $# -gt 0 ]; then mdfind -onlyin "$PWD" "$( les_args "$@" )"
    else echo "mdfind local - by content (&&)"; echo "Usage:    mdflc 'expr1' 'expr2' ..."
    fi
}
```
à placer dans son .profile
là encore, faut bien sûr échapper les arguments, surtout si on veut leur ajouter des wildcards (en particulier, typiquement '*' à gauche et/ou à droite <- si on préfère, on peut mettre plutôt dans les_args : kMDItemTextContent == '*$( ...)*'cd)

évidemment, faut que les fichiers aient été indexés par Spotlight


l'intérêt ? :mouais: pas énorme, mais c'était pour le sport  (et ça permet d'apporter une autre solution à la question intiale  )


je sors :rateau:


----------



## bompi (21 Avril 2006)

Voici un nouvel unixien parmi nous  Bienvenue !


----------



## FjRond (21 Avril 2006)

parasite a dit:
			
		

> note: si tu mets entre crochets des arguments dans le synopsis, c'est qu'ils ne sont pas nécessaires, ce qui est faux ici


Bien vu



			
				parasite a dit:
			
		

> l'intérêt ? :mouais: pas énorme, mais c'était pour le sport  (et ça permet d'apporter une autre solution à la question intiale  )


Vive le sport !


----------

