Comment récursivement grep
tous les répertoires et sous-répertoires?
find . | xargs grep "texthere" *
grep -rin xlsx *.pl
ne fonctionne pas pour moi sur Redhat Linux. J'obtiens une erreur "pas de correspondance".
Comment récursivement grep
tous les répertoires et sous-répertoires?
find . | xargs grep "texthere" *
grep -rin xlsx *.pl
ne fonctionne pas pour moi sur Redhat Linux. J'obtiens une erreur "pas de correspondance".
Réponses:
grep -r "texthere" .
Le premier paramètre représente l'expression régulière à rechercher, tandis que le second représente le répertoire à rechercher. Dans ce cas, .
signifie le répertoire courant.
Remarque: Cela fonctionne pour GNU grep, et sur certaines plates-formes comme Solaris, vous devez spécifiquement utiliser GNU grep par opposition à l'implémentation héritée. Pour Solaris, c'est la ggrep
commande.
AIX 5.3
par exemple.
Si vous connaissez l'extension ou le motif du fichier que vous souhaitez, une autre méthode consiste à utiliser l' --include
option:
grep -r --include "*.txt" texthere .
Vous pouvez également mentionner les fichiers à exclure --exclude
.
Si vous recherchez fréquemment du code, Ag (The Silver Searcher) est une alternative beaucoup plus rapide à grep, qui est personnalisée pour la recherche de code. Par exemple, il est récursif par défaut et ignore automatiquement les fichiers et répertoires répertoriés dans .gitignore
, vous n'avez donc pas à passer les mêmes options d'exclusion lourdes à grep ou find.
=
fonctionner très bien sur Ubuntu. PS: c'est censé être un espace à contre-courant, mais l'analyseur de démarque SO a échoué.
grep
, pas pour l'Ag, juste pour que vous le sachiez :)
--include "*.txt" --include "*.TXT"
Aussi:
find ./ -type f -print0 | xargs -0 grep "foo"
mais grep -r
c'est une meilleure réponse.
find . -type f -exec grep "foo" '{}' \;
fonctionne bien là où c'est pris en charge.
find ./ -type f -print0 | xargs -0 grep "foo"
J'utilise désormais toujours (même sous Windows avec GoW - Gnu sous Windows ):
grep --include="*.xxx" -nRHI "my Text to grep" *
Cela inclut les options suivantes:
--include=PATTERN
Réexaminez dans les répertoires en recherchant uniquement la correspondance des fichiers
PATTERN
.
-n, --line-number
Préfixez chaque ligne de sortie avec le numéro de ligne dans son fichier d'entrée.
(Remarque: phuclv ajoute dans les commentaires ce qui -n
diminue considérablement les performances , vous pouvez donc ignorer cette option)
-R, -r, --recursive
Lisez tous les fichiers sous chaque répertoire, récursivement; c'est l'équivalent de l'
-d recurse
option.
-H, --with-filename
Imprimez le nom de fichier pour chaque correspondance.
-I
Traitez un fichier binaire comme s'il ne contenait pas de données correspondantes;
c'est l'équivalent de l'--binary-files=without-match
option.
Et je peux ajouter ' i
' ( -nRHIi
), si je veux des résultats insensibles à la casse.
Je peux obtenir:
/home/vonc/gitpoc/passenger/gitlist/github #grep --include="*.php" -nRHI "hidden" *
src/GitList/Application.php:43: 'git.hidden' => $config->get('git', 'hidden') ? $config->get('git', 'hidden') : array(),
src/GitList/Provider/GitServiceProvider.php:21: $options['hidden'] = $app['git.hidden'];
tests/InterfaceTest.php:32: $options['hidden'] = array(self::$tmpdir . '/hiddenrepo');
vendor/klaussilveira/gitter/lib/Gitter/Client.php:20: protected $hidden;
vendor/klaussilveira/gitter/lib/Gitter/Client.php:170: * Get hidden repository list
vendor/klaussilveira/gitter/lib/Gitter/Client.php:176: return $this->hidden;
...
-R
option) aux dossiers.
*
ou .
est un modèle glob (interprété par le shell): unix.stackexchange.com/a/64695/7490 . ' .
' sélectionnera également les fichiers de points ou les dossiers de points (comme .git/
)
grep -rnI
mais j'ai appris que cela -n
diminue beaucoup les performances, donc je ne l'utilise que lorsque c'est vraiment nécessaire et normalement j'utiliserai-rI
Dans les systèmes POSIX, vous ne trouvez pas de -r
paramètre pour grep
et votre grep -rn "stuff" .
ne fonctionnera pas, mais si vous utilisez la find
commande, il:
find . -type f -exec grep -n "stuff" {} \; -print
Approuvé par Solaris
et HP-UX
.
-exec
option - le symbole {}
est une référence au nom de fichier actuellement trouvé parfind
outil (c'est-à-dire faire quelque chose avec le nom de fichier que nous avons trouvé), également l' -exec
option doit être terminée par le ;
symbole (pour marquer la fin des commandes exec), mais parce que c'est tout en cours d'exécution dans un shell, ce symbole doit être échappé .. et enfin l' -print
option permet à l' find
outil d'imprimer les noms de fichiers trouvés sur l'écran.
**
Utiliser des grep -r
œuvres, mais cela peut exagérer, en particulier dans les grands dossiers.
Pour une utilisation plus pratique, voici la syntaxe qui utilise la syntaxe de globalisation ( **
):
grep "texthere" **/*.txt
qui ne greps que des fichiers spécifiques avec le modèle sélectionné. Il fonctionne pour les shells pris en charge tels que Bash +4 ou zsh .
Pour activer cette fonction, exécutez: shopt -s globstar
.
Voir aussi: Comment trouver tous les fichiers contenant du texte spécifique sur Linux?
git grep
Pour les projets sous contrôle de version Git, utilisez:
git grep "pattern"
ce qui est beaucoup plus rapide.
ripgrep
Pour les grands projets, l'outil de grepping le plus rapide est ripgrep
qui récupère les fichiers de manière récursive par défaut:
rg "pattern" .
Il est construit sur le moteur regex de Rust qui utilise des automates finis, SIMD et des optimisations littérales agressives pour rendre la recherche très rapide. Consultez l' analyse détaillée ici .
Pour trouver le nom de files
with path
contenant récursivement la string
commande particulière d' utilisation ci-dessous pour UNIX
:
find . | xargs grep "searched-string"
pour Linux
:
grep -r "searched-string" .
trouver un fichier sur le UNIX
serveur
find . -type f -name file_name
trouver un fichier sur le serveur LINUX
find . -name file_name
Si vous souhaitez uniquement suivre les répertoires réels et non les liens symboliques,
grep -r "thingToBeFound" directory
Si vous souhaitez suivre les liens symboliques ainsi que les répertoires réels (attention à la récursion infinie),
grep -R "thing to be found" directory
Puisque vous essayez de grep récursivement, les options suivantes peuvent également vous être utiles:
-H: outputs the filename with the line
-n: outputs the line number in the file
Donc, si vous voulez trouver tous les fichiers contenant Dark Vador dans le répertoire en cours ou n'importe quel sous-répertoire et capturer le nom de fichier et le numéro de ligne, mais ne voulez pas que la récursion suive les liens symboliques, la commande serait
grep -rnH "Darth Vader" .
Si vous souhaitez retrouver toutes les mentions du mot chat dans l'annuaire
/home/adam/Desktop/TomAndJerry
et vous êtes actuellement dans l'annuaire
/home/adam/Desktop/WorldDominationPlot
et vous voulez capturer le nom de fichier mais pas le numéro de ligne d'une instance de la chaîne "chats", et vous voulez que la récursivité suive les liens symboliques si elle les trouve, vous pouvez exécuter l'une des opérations suivantes
grep -RH "cats" ../TomAndJerry #relative directory
grep -RH "cats" /home/adam/Desktop/TomAndJerry #absolute directory
La source:
exécution de "grep --help"
Une courte introduction aux liens symboliques, pour tous ceux qui lisent cette réponse et confus par ma référence à eux: https://www.nixtutor.com/freebsd/understanding-symbolic-links/
ag est ma façon préférée de le faire maintenant github.com/ggreer/the_silver_searcher . C'est fondamentalement la même chose que ack mais avec quelques optimisations supplémentaires.
Voici une brève référence. J'efface le cache avant chaque test (cf /ubuntu/155768/how-do-i-clean-or-disable-the-memory-cache )
ryan@3G08$ sync && echo 3 | sudo tee /proc/sys/vm/drop_caches
3
ryan@3G08$ time grep -r "hey ya" .
real 0m9.458s
user 0m0.368s
sys 0m3.788s
ryan@3G08:$ sync && echo 3 | sudo tee /proc/sys/vm/drop_caches
3
ryan@3G08$ time ack-grep "hey ya" .
real 0m6.296s
user 0m0.716s
sys 0m1.056s
ryan@3G08$ sync && echo 3 | sudo tee /proc/sys/vm/drop_caches
3
ryan@3G08$ time ag "hey ya" .
real 0m5.641s
user 0m0.356s
sys 0m3.444s
ryan@3G08$ time ag "hey ya" . #test without first clearing cache
real 0m0.154s
user 0m0.224s
sys 0m0.172s
Cela devrait fonctionner:
grep -R "texthere" *
Si vous recherchez un contenu spécifique dans tous les fichiers d'une structure de répertoires, vous pouvez utiliser find
car il est plus clair ce que vous faites:
find -type f -exec grep -l "texthere" {} +
Notez que -l
(downcase of L) affiche le nom du fichier qui contient le texte. Supprimez-le si vous souhaitez imprimer le match lui-même. Ou utilisez -H
pour obtenir le fichier avec la correspondance. Dans l'ensemble, d'autres alternatives sont:
find -type f -exec grep -Hn "texthere" {} +
Où -n
imprime le numéro de ligne.
find
solution à la fois éviter l' utilisation inutile xargs
et utiliser au +
lieu de \;
avec -exec
, évitant ainsi des tonnes de lancements de processus inutiles. :-)
C'est celui qui a fonctionné pour mon cas sur ma machine actuelle (git bash sur windows 7):
find ./ -type f -iname "*.cs" -print0 | xargs -0 grep "content pattern"
J'oublie toujours les -print0 et -0 pour les chemins avec des espaces.
EDIT: Mon outil préféré est maintenant à la place ripgrep: https://github.com/BurntSushi/ripgrep/releases . C'est vraiment rapide et a de meilleures valeurs par défaut (comme récursif par défaut). Même exemple que ma réponse d'origine mais en utilisant ripgrep:rg -g "*.cs" "content pattern"
grep -r "texthere" .
(délai de préavis à la fin)
(^ crédit: https://stackoverflow.com/a/1987928/1438029 )
Clarification:
grep -r "texthere" /
(grep récursivement tous les répertoires et sous-répertoires)
grep -r "texthere" .
(grep récursivement ces répertoires et sous-répertoires)
grep [options] PATTERN [FILE...]
[options]
-R, -r, --recursive
Lisez tous les fichiers sous chaque répertoire, récursivement.
C'est l'équivalent de l' option
-d recurse
ou--directories=recurse
.
$ grep --help
$ grep --help |grep recursive
-r, --recursive like --directories=recurse
-R, --dereference-recursive
ack
( http://beyondgrep.com/ )
En 2018, vous souhaitez utiliser ripgrep
ou the-silver-searcher
parce qu'ils sont beaucoup plus rapides que les alternatives.
Voici un répertoire avec 336 sous-répertoires de premier niveau:
% find . -maxdepth 1 -type d | wc -l
336
% time rg -w aggs -g '*.py'
...
rg -w aggs -g '*.py' 1.24s user 2.23s system 283% cpu 1.222 total
% time ag -w aggs -G '.*py$'
...
ag -w aggs -G '.*py$' 2.71s user 1.55s system 116% cpu 3.651 total
% time find ./ -type f -name '*.py' | xargs grep -w aggs
...
find ./ -type f -name '*.py' 1.34s user 5.68s system 32% cpu 21.329 total
xargs grep -w aggs 6.65s user 0.49s system 32% cpu 22.164 total
Sur Mac OS X, cela installe ripgrep
: brew install ripgrep
. Cela installe silver-searcher
: brew install the_silver_searcher
.
rg
a un avantage considérable sur le bricolage d'une commande récursive grep à partir de zéro. L' utilisation rg
: rg foo
. L' utilisation d' outils unix: find . | xargs grep foo
. Et si l'un de vos fichiers contient un devis, vous devez l'utiliser find . -print0 | xargs -0 grep foo
. Allez-vous vous en souvenir si vous l'utilisez plusieurs fois par an?
find . -type f -exec grep 'regex' {} +
ce qui est en effet facile à retenir si vous utilisez régulièrement ces outils. Mais vous devriez probablement exécuter ctags
ou etags
sur votre arbre source de toute façon si vous avez besoin de trouver des choses fréquemment.
Dans mon serveur IBM AIX (version du système d'exploitation: AIX 5.2), utilisez:
find ./ -type f -print -exec grep -n -i "stringYouWannaFind" {} \;
cela affichera le chemin / nom de fichier et le numéro de ligne relatif dans le fichier comme:
./inc/xxxx_x.h
2865: / ** Description: stringYouWannaFind * /
de toute façon, ça marche pour moi :)
Vous trouverez ci-dessous la commande de recherche String
récursive sur Unix
et Linux
environnement.
pour la UNIX
commande est:
find . -name "string to be searched" -exec grep "text" "{}" \;
pour la Linux
commande est:
grep -r "string to be searched" .
Pour une liste des drapeaux disponibles:
grep --help
Renvoie toutes les correspondances pour le texte d' expression rationnelle dans le répertoire courant, avec le numéro de ligne correspondant:
grep -rn "texthere" .
Renvoie toutes les correspondances pour texthere , en commençant par le répertoire racine, avec le numéro de ligne correspondant et en ignorant la casse:
grep -rni "texthere" /
drapeaux utilisés ici:
-r
récursif -n
numéro de ligne d'impression avec sortie -i
ignorer la casseJe suppose que c'est ce que vous essayez d'écrire
grep myText $(find .)
et cela peut être quelque chose d'autre utile si vous voulez trouver les fichiers grep hit
grep myText $(find .) | cut -d : -f 1 | sort | uniq
Notez que des find . -type f | xargs grep whatever
sortes de solutions se heurteront aux erreurs "Argument list to long" lorsqu'il y a trop de fichiers correspondant à find.
Le meilleur pari est grep -r
mais si ce n'est pas disponible, utilisez find . -type f -exec grep -H whatever {} \;
plutôt.
xargs
est spécifiquement une solution de contournement pour le problème «Liste d'arguments trop longue».
find . -type f | xargs -L 100 grep whatever
xargs
est standardisé pour avoir ce comportement hors de la boîte. "L' xargs
utilitaire doit limiter la longueur de la ligne de commande de telle sorte que lorsque la ligne de commande est invoquée, l'argument combiné et les listes d'environnement ... ne doivent pas dépasser {ARG_MAX} -2048 octets."
Voici une fonction récursive (testée légèrement avec bash et sh) qui traverse tous les sous-dossiers d'un dossier donné ($ 1) et utilise des grep
recherches pour une chaîne donnée ($ 3) dans des fichiers donnés ($ 2):
$ cat script.sh
#!/bin/sh
cd "$1"
loop () {
for i in *
do
if [ -d "$i" ]
then
# echo entering "$i"
cd "$i"
loop "$1" "$2"
fi
done
if [ -f "$1" ]
then
grep -l "$2" "$PWD/$1"
fi
cd ..
}
loop "$2" "$3"
L'exécuter et un exemple de sortie:
$ sh script start_folder filename search_string
/home/james/start_folder/dir2/filename