Recherche récursive de contenu de fichiers

SuperCed

Membre expert
Club iGen
20 Juin 2001
1 354
72
46
superced.rb38.eu
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!
 
Bloc de code:
% 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 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:
Bloc de code:
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.
 
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.
 
Merci c'est ce que je cherchais.
Existe-il un moyen de lancer l'indexation Spotlight via le terminal?
 
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.
 
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 :
Bloc de code:
% 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:
Bloc de code:
#!/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 :
Bloc de code:
% 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
 
FjRond a dit:
voici un petit script que je me suis fait pour la recherche dans mon répertoire personnel:
Bloc de code:
#!/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
ou plus simplement :
Bloc de code:
#!/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) :
Bloc de code:
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 :D (et ça permet d'apporter une autre solution à la question intiale :p )


je sors :rateau:
 
:up: Voici un nouvel unixien parmi nous ;) Bienvenue !
 
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 :D (et ça permet d'apporter une autre solution à la question intiale :p )
Vive le sport ! :)