web-dev-qa-db-fra.com

Bash: existe-t-il un moyen de rechercher une chaîne particulière dans un répertoire de fichiers?

doublon possible:
Rechercher un modèle de texte sous Linux

Sous Bash, je me demandais s’il existait des commandes permettant de savoir si une chaîne particulière que vous recherchez existe dans les fichiers situés dans le répertoire actuel dans lequel vous vous trouvez.

Supposons que vous cherchiez la fonction 'toUpperCase ()' dans un ensemble de fichiers C de votre répertoire actuel. Il y a beaucoup de fichiers, vous ne voudriez donc pas les ouvrir manuellement à l'aide de vim et vérifier la chaîne 'toUpperCase' car cela prendrait beaucoup de temps. Si ce n'est pas une ligne de commande bash, existe-t-il une autre méthode pour le faire efficacement?

41
Dark Templar

Avec grep:

grep -R "toUppercase()" *

Ou, si vous avez ack-grep installé, simplement:

ack-grep "toUppercase"

Si vous souhaitez limiter la recherche dans les fichiers C, utilisez ack-grep:

ack-grep -cc "toUppercase()"

ack-grep peut également être installé sur OSX mais l'exécutable s'appelle simplement ack.

60

L'outil de recherche de texte standard est grep .

Pour rechercher la chaîne toUpperCase( dans tous les fichiers .c du répertoire actuel:

grep -F 'toUpperCase(' *.c

Si vous souhaitez également consulter les sous-répertoires:

grep -r --include='*.c' -F 'toUpperCase('

Si vous recherchez des appels de fonction C, alors ctags peut être un meilleur ajustement. Vous l'exécutez une fois sur tous vos fichiers source pour créer un index d'identifiants, puis utilisez votre éditeur pour naviguer entre les appels. Tous les éditeurs de type vi peuvent utiliser le fichier TAGS de ctags. Si vous utilisez Emacs, exécutez le programme similaire etags.

10
Gilles

Oui, l'outil s'appelle grep .

La commande grep recherche dans un ou plusieurs fichiers d'entrée les lignes contenant une correspondance avec un modèle spécifié. Par défaut, grep affiche les lignes correspondantes.

L'utilisation de base est:

grep something somewhere

Ou plus spécifiquement:

grep [some options] pattern file

Dans un cas très simple, vous souhaitez récursivement rechercher dans tous les fichiers, vous devez donc fournir l'option -r. Si vous ne vous souciez pas des majuscules ou des minuscules, faites-le en respectant la casse avec l'option -i.

grep -ri "touppercase()" .

Si vous souhaitez uniquement les parties correspondantes, utilisez l'option -o.

Grep peut utiliser des expressions régulières , et il possède un manuel énorme .

3
slhck

grep est la réponse standard - en utilisant l’indicateur -r pour effectuer une recherche récursive ou en conjonction avec find (discussion et exemples dans d’autres questions de ce site, telles que celle-ci )

Dernièrement, mon choix préféré est ack. Il n'est probablement pas installé sur votre ordinateur, mais vous pouvez l'installer à l'aide d'apt-get sur Ubuntu ou simplement le télécharger. Les liens, les instructions et les raisons pour lesquelles il vaut mieux que grep sont disponibles à l'adresse http://betterthangrep.com/

2
Doug Harris

find ET grep

find myproject -name '*.c' -exec grep 'toUpperCase(' {} \; -print

pourquoi pas seulement grep?

grep -r string . recurse dans tous les fichiers du répertoire en cours. Si vous avez des fichiers objet ou d’autres fichiers binaires, vous pouvez obtenir une correspondance avec des résultats binaires. déchet. Si vous avez également des fichiers fifos ou de périphérique dans votre sous-répertoire, vous risquez d’avoir des conséquences inconnues ou inattendues.

grep string *.c ne recherche que dans les répertoires actuels .c.

grep string **/*.c fait une recherche dans tous les sous-répertoires. Toutefois, si vous avez un très grand nombre de fichiers .c, vous courez le risque de dépasser le nombre maximal d'extensions pour le glob Shell. L’extension doit également avoir lieu en premier, ce qui signifie une traversée complète de l’arbre avant le début de la grep.

1
dietbuddha

Grep fera l'affaire, mais un peu de script supplémentaire aidera à trouver le nom du fichier et la ligne exacte référencée. Si c'est ce que vous voulez, je trouve que ce qui suit fonctionne bien. Je l’ai sauvegardé en tant que script Shell et lui passe la valeur que je veux comme première option de ligne de commande.

for i in $(ls)
do
    cat $i 2> /dev/null | grep $1 > /dev/null 2>&1
    STATUS=$?
    if [ $STATUS  -eq 0 ] ; then
        echo $i
        cat $i | grep -n $1
    fi
done
0
Tim Brigham

Je trouve intéressant que personne n’ait répondu à votre question précise: "Comment savoir si une chaîne particulière existe dans les fichiers situés dans le répertoire actuel". Autant que je sache, il n'y a pas d'option grep qui indique uniquement si une correspondance a été trouvée dans un groupe de fichiers. L'option la plus proche est -l pour lister le ou les noms de fichiers. La réponse la plus proche parmi ceux-ci est de tim, avec quelques légères modifications:

#!/usr/bin/bash

for i in $(ls *.c 2> /dev/null)
do
    cat $i 2> /dev/null | grep $1 > /dev/null 2>&1
    STATUS=$?

    if [ $STATUS  -eq 0 ] ; then
        echo "Found"
        exit
    fi
done

echo "Not found"

Vous pouvez rendre ce script shell plus générique en acceptant un second argument pour l'extension de fichier sans trop de difficulté.

doug

0
SnoopDougieDoug