Je ne suis pas sûr:
grep -r -i 'the brown dog' /*
c'est vraiment ce que vous vouliez dire. Cela signifierait que grep récursivement dans tous les fichiers et répertoires non cachés de /(mais qu'il faut tout de même regarder à l'intérieur des fichiers et des répertoires cachés).
En supposant que vous vouliez dire:
grep -r -i 'the brown dog' /
Quelques points à noter:
- Toutes les
grepimplémentations ne prennent pas en charge -r. Et parmi ceux qui le font, les comportements diffèrent: certains suivent les liens symboliques vers des répertoires lorsqu’ils parcourent l’arborescence (ce qui signifie que vous pouvez chercher plusieurs fois dans le même fichier ou même exécuter des boucles infinies), d’autres ne le feront pas. Certains vont regarder à l'intérieur des fichiers de périphériques (cela prendra un certain temps, /dev/zeropar exemple), des pipes ou des fichiers binaires ..., d'autres pas.
- C'est efficace, car il
grepcommence à regarder à l'intérieur des fichiers dès qu'il les découvre. Mais alors qu'il cherche dans un fichier, il ne cherche plus de fichiers dans lesquels chercher (ce qui est probablement aussi bien dans la plupart des cas)
Votre:
find / -type f -exec grep -i 'the brown dog' {} \;
(supprimé le -rqui n'a pas de sens ici) est terriblement inefficace parce que vous en exécutez un greppar fichier. ;ne devrait être utilisé que pour les commandes qui n'acceptent qu'un seul argument. De plus ici, comme il grepne regarde que dans un seul fichier, le nom du fichier ne sera pas imprimé, vous ne saurez pas où se trouvent les correspondances.
Vous ne regardez pas dans les fichiers de périphérique, les pipes, les liens symboliques ..., vous ne suivez pas les liens symboliques, mais vous recherchez toujours des éléments tels que /proc/mem.
find / -type f -exec grep -i 'the brown dog' {} +
serait beaucoup mieux parce que le moins de grepcommandes possible serait exécuté. Vous obtiendrez le nom du fichier à moins que la dernière exécution ne comporte qu'un seul fichier. Pour cela, il vaut mieux utiliser:
find / -type f -exec grep -i 'the brown dog' /dev/null {} +
ou avec GNU grep:
find / -type f -exec grep -Hi 'the brown dog' {} +
Notez que grepcela ne sera pas démarré avant d' findavoir trouvé suffisamment de fichiers pour qu'il puisse être mâché, il y aura donc un délai initial. Et findne poursuivra pas la recherche d'autres fichiers tant que le précédent grepn'est pas revenu. L'attribution et le passage de la liste des gros fichiers ont un impact (probablement négligeable), donc dans l'ensemble, cela sera probablement moins efficace qu'un grep -rlien qui ne suit pas un lien symbolique ou ne regarde pas à l'intérieur des périphériques.
Avec les outils GNU:
find / -type f -print0 | xargs -r0 grep -Hi 'the brown dog'
Comme ci-dessus, le moins d’ grepinstances possibles seront exécutées, mais findcontinueront à rechercher davantage de fichiers pendant que la première grepinvocation est effectuée à l’intérieur du premier lot. Cela peut ou peut ne pas être un avantage si. Par exemple, avec des données stockées sur les disques durs de rotation, findet l' grepaccès aux données stockées à différents endroits sur le disque va ralentir le débit du disque en provoquant la tête du disque de se déplacer en permanence. Dans une configuration RAID (où findet greppeut accéder à différents disques) ou sur des SSD, cela peut faire une différence positive.
Dans une configuration RAID, l'exécution de plusieurs appels simultanés grep peut également améliorer les choses. Toujours avec des outils GNU sur un stockage RAID1 avec 3 disques,
find / -type f -print0 | xargs -r0 -P2 grep -Hi 'the brown dog'
pourrait augmenter la performance de manière significative. Notez cependant que le second grepne sera démarré que lorsque suffisamment de fichiers auront été trouvés pour remplir la première grepcommande. Vous pouvez ajouter une -noption à xargspour que cela se produise plus tôt (et transmettre moins de fichiers par grepappel).
Notez également que si vous redirigez la xargssortie vers un périphérique autre qu'un terminal, le grepss commencera à mettre en tampon leur sortie, ce qui signifie que la sortie de ces greps sera probablement mal entrelacée. Vous devriez les utiliser stdbuf -oL(là où ils sont disponibles, comme sur GNU ou FreeBSD) pour résoudre ce problème (vous pouvez toujours rencontrer des problèmes avec de très longues lignes (généralement> 4 Ko)) ou demandez à chacun d’écrire leur sortie dans un fichier séparé et de les concaténer. tout à la fin.
Ici, la chaîne que vous recherchez est fixe (pas une expression rationnelle), donc l'utilisation de l' -Foption pourrait faire la différence (peu probable que les grepimplémentations sachent déjà l'optimiser).
Une autre chose qui pourrait faire une grande différence est de fixer les paramètres régionaux sur C si vous êtes dans des paramètres régionaux multi-octets:
find / -type f -print0 | LC_ALL=C xargs -r0 -P2 grep -Hi 'the brown dog'
Pour éviter de regarder à l'intérieur /proc, /sys..., utilisez -xdevet spécifiez les systèmes de fichiers dans lesquels vous souhaitez effectuer la recherche:
LC_ALL=C find / /home -xdev -type f -exec grep -i 'the brown dog' /dev/null {} +
Ou élaguez les chemins que vous souhaitez exclure explicitement:
LC_ALL=C find / \( -path /dev -o -path /proc -o -path /sys \) -prune -o \
-type f -exec grep -i 'the brown dog' /dev/null {} +