Rechercher des fichiers contenant un texte donné

153

Dans bash, je veux retourner le nom du fichier (et le chemin du fichier) pour chaque fichier de type .php|.html|.jscontenant la chaîne insensible à la casse"document.cookie" | "setcookie"

Comment pourrais-je faire ça?

Owen
la source
4
Avez-vous envisagé d'utiliser simplement grep? cyberciti.biz/faq/grep-in-bash
Terrance
Ce titre est assez trompeur. "trouver-des-fichiers-contenant-un-texte-donné"
Josh C

Réponses:

212
egrep -ir --include=*.{php,html,js} "(document.cookie|setcookie)" .

Le rdrapeau signifie une recherche récursive (recherche dans les sous-répertoires). Le idrapeau signifie insensible à la casse.

Si vous voulez juste des noms de fichiers, ajoutez l' indicateur l(minuscules L):

egrep -lir --include=*.{php,html,js} "(document.cookie|setcookie)" .
bear24rw
la source
cela ne semble pas fonctionner pour moi (du moins pas sur mac) .... se bloque juste ... egrep -lir --include = * "repo" egrep: avertissement: recherche récursive de stdin
Dean Hiller
13
Vous avez oublié d'ajouter le chemin à rechercher. Le chemin est «.» dans l'exemple ci-dessus. Dans votre cas, le script attend l'entrée pour rechercher sur stdin. Essayez: egrep -lir --include = * "repo" / (ou tout autre chemin)
LodeRunner
1
grep -E ... >egrep ...
Aman
J'ai eu une erreur grep: (error|fail): No such file or directorysur Ubuntu Desktop 16; des indices?
Nam G VU
Pour que cela fonctionne, je devais sauter le * avec \. so I have--include=\*.{php,html,js}
Mehrad Mahmoudian
53

Essayez quelque chose comme grep -r -n -i --include="*.html *.php *.js" searchstrinhere .

le -irend insensible à la casse

le .à la fin signifie que vous voulez commencer à partir de votre répertoire actuel, cela peut être remplacé par n'importe quel répertoire.

les -rmoyens le font de manière récursive, dans l'arborescence des répertoires

le -nimprime le numéro de ligne pour les correspondances.

le --includevous permet d'ajouter des noms de fichiers, des extensions. Caractères génériques acceptés

Pour plus d'informations, voir: http://www.gnu.org/software/grep/

Raoul
la source
4
Ou peut-être utiliser l' -loption (simplement imprimer les noms de fichiers qui correspondent) au lieu de-n
glenn jackman
15

findeux et greppour la chaîne:

Cela trouvera tous les fichiers de vos 3 types dans / starting / path et grep pour l'expression régulière '(document\.cookie|setcookie)'. Divisez sur 2 lignes avec la barre oblique inverse juste pour la lisibilité ...

find /starting/path -type f -name "*.php" -o -name "*.html" -o -name "*.js" | \
 xargs egrep -i '(document\.cookie|setcookie)'
Michael Berkowski
la source
1
Comme l'utilisation universelle de find, mais à mon avis, il vaut mieux utiliser-exec grep -l 'sth' {} \;
NGix
Merci @Michael Berkowski De cette façon le plus rapide plus de 5 ou 8 fois # egrep -ir --include=file.foo "(foo|bar)" /dirsur un répertoire de poids ~ 500 Go .
Qh0stM4N
9

Sonne comme un travail parfait pour grepou peut-être ack

Ou cette magnifique construction:

find . -type f \( -name *.php -o -name *.html -o -name *.js \) -exec grep "document.cookie\|setcookie" /dev/null {} \;
Fredrik Pihl
la source
+1 L'utilisation -exec grep...est meilleure que ma xargsméthode car elle ne s'étouffera pas avec les espaces dans les noms de fichiers.
Michael Berkowski
@MichaelBerkowski: Vous pouvez l' utiliser comme ceci pour traiter les espaces dans les noms de fichiers: find . -type f -print0 | xargs -0 -I {} grep "search_string" {}. Bien sûr, les autres options peuvent également être ajoutées.
Pascal
4
find . -type f -name '*php' -o -name '*js' -o -name '*html' |\
xargs grep -liE 'document\.cookie|setcookie'
nos
la source
3

Juste pour inclure une autre alternative, vous pouvez également utiliser ceci:

find "/starting/path" -type f -regextype posix-extended -regex "^.*\.(php|html|js)$" -exec grep -EH '(document\.cookie|setcookie)' {} \;

Où:

  • -regextype posix-extendedindique à findquel type de regex s'attendre
  • -regex "^.*\.(php|html|js)$"indique à findl'expression régulière elle-même que les noms de fichiers doivent correspondre
  • -exec grep -EH '(document\.cookie|setcookie)' {} \;dit findd'exécuter la commande (avec ses options et arguments) spécifiée entre l' -execoption et le \;pour chaque fichier qu'il trouve, où {}représente l'emplacement du chemin du fichier dans cette commande.

    tandis que

    • EL'option indique grepd'utiliser une expression régulière étendue (pour prendre en charge les parenthèses) et ...
    • HL'option indique grepd'imprimer les chemins de fichiers avant les correspondances.

Et, étant donné cela, si vous ne voulez que des chemins de fichiers, vous pouvez utiliser:

find "/starting/path" -type f -regextype posix-extended -regex "^.*\.(php|html|js)$" -exec grep -EH '(document\.cookie|setcookie)' {} \; | sed -r 's/(^.*):.*$/\1/' | sort -u

  • |[pipe] envoie la sortie de findà la commande suivante après ceci (qui est sed, alors sort)
  • roption indique sedd'utiliser une expression régulière étendue.
  • s/HI/BYE/dit sedde remplacer chaque première occurrence (par ligne) de "HI" par "BYE" et ...
  • s/(^.*):.*$/\1/lui dit de remplacer l'expression régulière (^.*):.*$(signifiant un groupe [truc entouré par ()] comprenant tout [ .*= un ou plusieurs de n'importe quel caractère] depuis le début de la ligne [ ^] jusqu'à 'le premier': 'suivi de n'importe quoi jusqu'à' la fin de line [ $]) par le premier groupe [ \1] de l'expression régulière remplacée.
  • uindique à sort de supprimer les entrées en double (à prendre sort -ucomme facultatif).

... Loin d'être la manière la plus élégante. Comme je l'ai dit, mon intention est d'élargir l'éventail des possibilités (et aussi de donner des explications plus complètes sur certains outils que vous pourriez utiliser).

Pedro Vernetti
la source