web-dev-qa-db-fra.com

Comment puis-je grep récursivement?

Comment puis-je récursivement grep tous les répertoires et sous-répertoires?

find . | xargs grep "texthere" *
1584
wpiri
grep -r "texthere" .

Le premier paramètre représente l'expression régulière à rechercher, tandis que le second représente le répertoire dans lequel effectuer la recherche. Dans ce cas, . signifie le répertoire en cours.

Remarque: Cela fonctionne pour GNU grep. Sur certaines plates-formes telles que Solaris, vous devez utiliser spécifiquement GNU grep, par opposition à une implémentation héritée. Pour Solaris, il s'agit de la commande ggrep.

2375
Vinko Vrsalovic

Si vous connaissez l'extension ou le motif du fichier que vous souhaitez, une autre méthode consiste à utiliser l'option --include:

grep -r --include "*.txt" texthere .

Vous pouvez également mentionner des fichiers à exclure avec --exclude.

Ag

Si vous recherchez fréquemment dans le code, Ag (The Silver Searcher) est une alternative beaucoup plus rapide que grep, qui est personnalisé pour la recherche de code. Par exemple, il est récursif par défaut et ignore automatiquement les fichiers et les répertoires listés dans .gitignore, vous n'avez donc pas besoin de passer continuellement les mêmes options d'exclusion encombrantes à grep ou à find.

646
christangrant

Aussi:

find ./ -type f -print0 | xargs -0 grep "foo"

mais grep -r est une meilleure réponse.

122
Kurt

J'utilise maintenant 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

Recurse dans les répertoires recherchant uniquement les fichiers correspondant à 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 que -n réduit considérablement les performances de la sorte , vous voudrez donc peut-être ignorer cette option)

-R, -r, --recursive

Lire tous les fichiers sous chaque répertoire, de manière récursive; c'est équivalent à l'option -d recurse.

-H, --with-filename

Imprimez le nom de fichier pour chaque correspondance.

-I     

Traiter un fichier binaire comme s'il ne contenait pas de données correspondantes.
est équivalent à l'option --binary-files=without-match.

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;
...
109
VonC

Dans les systèmes POSIX, vous ne trouvez pas le paramètre -r pour grep et votre grep -rn "stuff" . ne fonctionnera pas, mais si vous utilisez la commande find, il va:

find . -type f -exec grep -n "stuff" {} \; -print

Convenu par Solaris et HP-UX.

22
rook

globbing _**_

Utiliser _grep -r_ fonctionne, mais cela peut être excessif, en particulier dans les grands dossiers.

Pour une utilisation plus pratique, voici la syntaxe qui utilise syntaxe globbing (_**_):

_grep "texthere" **/*.txt
_

qui greps que des fichiers spécifiques avec motif sélectionné motif. Cela fonctionne pour les shells supportés tels que Bash +4 ou zsh .

Pour activer cette fonctionnalité, exécutez: _shopt -s globstar_.

Voir aussi: Comment trouver tous les fichiers contenant du texte spécifique sous 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 projets plus volumineux, l'outil de recherche de référence le plus rapide est ripgrep .

_rg "pattern" .
_

Il est construit sur le moteur de regex de Rust qui utilise des automates finis, SIMD et des optimisations littérales agressives pour rendre la recherche très rapide. Vérifiez le analyse détaillée ici .

19
kenorb

juste les noms de fichiers peuvent être utiles aussi

grep -r -l "foo" .
11
chim

Pour trouver le nom de files avec path contenant récursivement le string, utilisez la commande ci-dessous pour UNIX:

find . | xargs grep "searched-string"

pour Linux:

grep -r "searched-string" .

trouver un fichier sur le serveur UNIX

find . -type f -name file_name

trouver un fichier sur le serveur LINUX

find . -name file_name
11

Si vous voulez seulement suivre les répertoires réels, et non les liens symboliques,

grep -r "thingToBeFound" directory

Si vous souhaitez suivre des liens symboliques ainsi que des répertoires réels (faites 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 Darth Vader dans le répertoire actuel ou dans n'importe quel sous-répertoire et capturer le nom du fichier et le numéro de ligne, mais que vous ne voulez pas que la récursivité suive des liens symboliques, la commande sera:

grep -rnH "Darth Vader" .

Si vous voulez trouver toutes les mentions du chat Word dans le répertoire

/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'aucune instance de la chaîne "chats", et vous voulez que la récursivité suive des 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:

en cours d'exécution "grep --help"

Une brève introduction aux liens symboliques, pour tous ceux qui lisent cette réponse et qui ne comprend pas ce que je pense d'eux: https://www.nixtutor.com/freebsd/understanding-symbolic-links/

9
SarcasticSully

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 un repère court. J'efface le cache avant chaque test (cf https://askubuntu.com/questions/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
8
dranxo

Ceci 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 options -print0 et -0 pour les chemins avec des espaces.

EDIT: Mon outil préféré est maintenant ripgrep: https://github.com/BurntSushi/ripgrep/releases . C'est vraiment rapide et a de meilleurs paramètres 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"

6
arkod

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 (case inférieure de L) affiche le nom du fichier contenant le texte. Supprimez-le si vous souhaitez imprimer la correspondance elle-même. Ou utilisez -H pour obtenir le fichier avec la correspondance. Tous ensemble, les autres alternatives sont:

find -type f -exec grep -Hn "texthere" {} +

-n imprime le numéro de ligne.

6
fedorqui

Cela devrait fonctionner:

grep -R "texthere" *
5
sumit kumar

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 leurs sous-répertoires)

grep -r "texthere" . (récursivement grep ces répertoires et sous-répertoires)

grep récursif

grep [options] PATTERN [FILE...]

[Les options]

-R, -r, --recursive

Lire tous les fichiers sous chaque répertoire, de manière récursive.

Cela équivaut à l'option -d recurse ou --directories=recurse.

http://linuxcommand.org/man_pages/grep1.html

grep aide

$ grep --help

$ grep --help |grep recursive
  -r, --recursive           like --directories=recurse
  -R, --dereference-recursive

Des alternatives

ack ( http://beyondgrep.com/ )

ag ( http://github.com/ggreer/the_silver_searcher )

4
Geoffrey Hale

En 2018, vous souhaitez utiliser ripgrep ou the-silver-searcher car ils sont bien 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 OSX, cela installe ripgrep: brew install ripgrep. Ceci installe silver-searcher: brew install the_silver_searcher.

4
hughdbrown

Dans mon serveur IBM AIX (version du système d'exploitation: AIX 5.2), utilisez:

find ./ -type f -print -exec grep -n -i "stringYouWannaFind" {} \; 

ceci affichera le chemin/nom du 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:)

3
user3606336

Vous trouverez ci-dessous la commande permettant de rechercher de manière récursive String dans les environnements Unix et Linux.

pour UNIX la commande est:

find . -name "string to be searched" -exec grep "text" "{}" \;

pour Linux la commande est:

grep -r "string to be searched" .
3

Je 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
2
Victor Faria

Pour une liste des drapeaux disponibles:

grep --help 

Renvoie toutes les correspondances pour le regexp texthere dans le répertoire en cours, 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 avec sortie
  • -i ignorer la casse
2
JSON C11

Notez que find . -type f | xargs grep whatever sortes de solutions se heurteront à des erreurs "Liste d'arguments trop longue" lorsque trop de fichiers correspondent à find.

Le meilleur choix est grep -r mais si ce n'est pas disponible, utilisez find . -type f -exec grep -H whatever {} \; à la place.

1
m.thome

Juste pour le plaisir, une recherche rapide et sale des fichiers * .txt si la réponse @christangrant est trop difficile à taper :-)

grep -r texthere .|grep .txt

1
PJ Brunet

Voici une fonction récursive (légèrement testée avec bash et sh) qui parcourt tous les sous-dossiers d’un dossier donné ($ 1) et utilise grep pour rechercher la 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
0
James Brown