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
grep
implé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/zero
par exemple), des pipes ou des fichiers binaires ..., d'autres pas.
- C'est efficace, car il
grep
commence à 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 -r
qui n'a pas de sens ici) est terriblement inefficace parce que vous en exécutez un grep
par fichier. ;
ne devrait être utilisé que pour les commandes qui n'acceptent qu'un seul argument. De plus ici, comme il grep
ne 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 grep
commandes 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 grep
cela ne sera pas démarré avant d' find
avoir trouvé suffisamment de fichiers pour qu'il puisse être mâché, il y aura donc un délai initial. Et find
ne poursuivra pas la recherche d'autres fichiers tant que le précédent grep
n'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 -r
lien 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’ grep
instances possibles seront exécutées, mais find
continueront à rechercher davantage de fichiers pendant que la première grep
invocation 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, find
et l' grep
accè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ù find
et grep
peut 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 grep
ne sera démarré que lorsque suffisamment de fichiers auront été trouvés pour remplir la première grep
commande. Vous pouvez ajouter une -n
option à xargs
pour que cela se produise plus tôt (et transmettre moins de fichiers par grep
appel).
Notez également que si vous redirigez la xargs
sortie vers un périphérique autre qu'un terminal, le greps
s commencera à mettre en tampon leur sortie, ce qui signifie que la sortie de ces grep
s 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' -F
option pourrait faire la différence (peu probable que les grep
implé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 -xdev
et 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 {} +