J'essaie de trouver un moyen d'analyser l'ensemble de mon système Linux pour tous les fichiers contenant une chaîne de texte spécifique. Juste pour clarifier, je cherche du texte dans le fichier, pas dans le nom du fichier.
Quand je cherchais comment faire cela, je suis tombé sur cette solution deux fois:
find / -type f -exec grep -H 'text-to-find-here' {} \;
Mais ça ne marche pas. Il semble afficher tous les fichiers du système.
Est-ce proche de la bonne façon de procéder? Sinon, comment dois-je? Cette capacité à trouver des chaînes de texte dans des fichiers serait extrêmement utile pour certains projets de programmation que je fais.
.
comme un caractère générique à un seul caractère, entre autres. Mon conseil est de toujours utiliser fgrep ou egrep.-H
par-l
(et peut-êtregrep
parfgrep
). Pour exclure des fichiers avec certains modèles de noms, vous utiliseriezfind
d'une manière plus avancée. Il vaut la peine d'apprendre à utiliserfind
, cependant. Justementman find
.find … -exec <cmd> +
est plus facile à taper et plus rapide quefind … -exec <cmd> \;
. Il ne fonctionne que s'il<cmd>
accepte un nombre quelconque d'arguments de nom de fichier. Le gain de temps d'exécution est particulièrement important s'il<cmd>
est lent à démarrer comme les scripts Python ou Ruby.grep "pattern" path/*.txt
Réponses:
Procédez comme suit:
-r
ou-R
est récursif,-n
est le numéro de ligne, et-w
signifie correspondre au mot entier.-l
(L minuscule) peut être ajouté pour donner simplement le nom de fichier des fichiers correspondants.Avec ces derniers ,
--exclude
,--include
,--exclude-dir
drapeaux pourraient être utilisés pour la recherche efficace:Cela ne recherchera que les fichiers ayant des extensions .c ou .h:
Cela exclura la recherche de tous les fichiers se terminant par l'extension .o:
Pour les répertoires, il est possible d'exclure un ou des répertoires particuliers via le
--exclude-dir
paramètre. Par exemple, cela exclura les répertoires dir1 /, dir2 / et tous correspondant à * .dst /:Cela fonctionne très bien pour moi, pour atteindre presque le même objectif que le vôtre.
Pour plus d'options, vérifiez
man grep
.la source
r
option soit paresseuse (traverse d'abord en profondeur, puis s'arrête après le premier répertoire), tandis qu'elleR
est gourmande (traversera correctement tout l'arbre).R
fr parcourrar
les deux répertoires correctement, maisR
suivra des liens symboliques.Vous pouvez utiliser
grep -ilR
:i
signifie ignorer la casse (facultatif dans votre cas).R
signifie récursif.l
signifie "afficher le nom du fichier, pas le résultat lui-même"./
signifie commencer à la racine de votre machine.la source
-i
ralentit beaucoup, alors ne l'utilisez pas si ce n'est pas nécessaire. Testez-le dans un certain répertoire puis généralisez. Il devrait être terminé en quelques minutes. Je pense qu'une expression régulière le ralentirait. Mais mes commentaires sont basés sur des suppositions, je vous propose de le tester avectime
en face de la ligne./*
c'est pour ça. Quoi qu'il en soit, je viens de le tester et j'ai remarqué que cela/
fonctionne.fgrep is the same as grep -F -> Interpret PATTERN as a list of fixed strings
.grep -Ril "text-to-find-here" ~/sites/
ou utiliser. pour le répertoire actuelgrep -Ril "text-to-find-here" .
Vous pouvez utiliser ack . C'est comme grep pour le code source. Vous pouvez scanner l'ensemble de votre système de fichiers avec.
Faites juste:
Dans votre répertoire racine.
Vous pouvez également utiliser des expressions régulières , spécifier le type de fichier, etc.
MISE À JOUR
Je viens de découvrir The Silver Searcher , qui est comme ack mais 3 à 5 fois plus rapide et ignore même les modèles d'un
.gitignore
fichier.la source
Vous pouvez utiliser:
Le
r
signifie récursif et va donc rechercher dans le chemin spécifié et aussi dans ses sous-répertoires. Cela vous indiquera le nom du fichier et imprimera la ligne dans le fichier où la chaîne apparaît.Ou une commande similaire à celle que vous essayez (exemple:) pour rechercher dans tous les fichiers javascript (* .js):
Cela imprimera les lignes dans les fichiers où le texte apparaît, mais cela n'imprimera pas le nom du fichier.
En plus de cette commande, nous pouvons également écrire ceci: grep -rn "Chaîne à rechercher" / chemin / vers / répertoire / ou / fichier -r: recherche récursive n: le numéro de ligne sera affiché pour les correspondances
la source
Vous pouvez utiliser ceci:
la source
Liste des noms de fichiers contenant un texte donné
Tout d'abord, je crois que vous avez utilisé
-H
au lieu de-l
. Vous pouvez également essayer d'ajouter le texte entre guillemets suivi de{} \
.Exemple
Supposons que vous recherchez des fichiers contenant du texte spécifique "Licence Apache" dans votre répertoire. Il affichera des résultats quelque peu similaires à ceux ci-dessous (la sortie sera différente en fonction du contenu de votre répertoire).
Supprimer la sensibilité à la casse
Même si vous n'êtes pas habitué au cas comme "texte" vs "TEXTE", vous pouvez utiliser le
-i
commutateur pour ignorer la casse. Vous pouvez lire plus de détails ici .J'espère que cela vous aidera.
la source
find
passera tous les chemins qu'elle trouve à la commandegrep -l "text-to-find-here" <file found>"
. Vous pouvez ajouter des restrictions au nom de fichier, par exemplefind / -iname "*.txt"
pour rechercher uniquement dans les fichiers dont le nom se termine par.txt
-iname
casse est insensible, ce qui signifie qu'il trouverait également des fichiers .TXT, par exemple, ainsi que TxT et TXt et ainsi de suite.grep
( GNU ou BSD )Vous pouvez utiliser l'
grep
outil pour rechercher récursivement le dossier actuel, comme:Remarque:
-r
- Recherche récursivement dans les sous-répertoires.Vous pouvez également utiliser la syntaxe de globalisation pour rechercher dans des fichiers spécifiques tels que:
Remarque: En utilisant l' option globbing (
**
), il analyse tous les fichiers de manière récursive avec une extension ou un motif spécifique. Pour activer cette syntaxe, exécutez:shopt -s globstar
. Vous pouvez également utiliser**/*.*
pour tous les fichiers (sauf caché et sans extension) ou tout autre modèle.Si vous avez l'erreur que votre argument est trop long, envisagez de restreindre votre recherche ou utilisez
find
plutôt une syntaxe telle que:Vous pouvez également utiliser
ripgrep
.ripgrep
Si vous travaillez sur des projets plus importants ou de gros fichiers, vous devez utiliser à la
ripgrep
place, comme:Découvrez les documents, les étapes d'installation ou le code source sur la page du projet GitHub .
Il est beaucoup plus rapide que tout autre outil comme GNU / BSD
grep
,ucg
,ag
,sift
,ack
,pt
ou similaire, puisqu'il est construit sur le dessus du moteur regex de Rust qui utilise des automates finis, SIMD et optimisations littérales agressives pour faire une recherche très rapide.Il prend en charge les modèles ignorés spécifiés dans les
.gitignore
fichiers, de sorte qu'un seul chemin de fichier peut être comparé à plusieurs modèles glob simultanément.Vous pouvez utiliser les paramètres communs tels que:
-i
- Recherche insensible.-I
- Ignorez les fichiers binaires.-w
- Rechercher les mots entiers (contrairement à la correspondance partielle des mots).-n
- Montrez la ligne de votre match.-C
/--context
(par exemple-C5
) - Augmente le contexte, de sorte que vous voyez le code environnant.--color=auto
- Marquez le texte correspondant.-H
- Affiche le nom du fichier où se trouve le texte.-c
- Affiche le nombre de lignes correspondantes. Peut être combiné avec-H
.la source
Si votre
grep
ne prend pas en charge la recherche récursive, vous pouvez combinerfind
avecxargs
:Je trouve cela plus facile à retenir que le format pour
find -exec
.Cela affichera le nom de fichier et le contenu de la ligne correspondante, par exemple
Drapeaux facultatifs que vous voudrez peut-être ajouter à
grep
:-i
- recherche insensible à la casse-l
- afficher uniquement le nom de fichier où la correspondance a été trouvée-h
- affiche uniquement la ligne qui correspond (pas le nom du fichier)la source
grep 'text-to-find-here'
sans nom de fichier s'ilfind
ne trouve rien. Cela va se bloquer et attendre la saisie de l'utilisateur! Ajouter--no-run-if-empty
en option àxargs
.find … -exec grep … +
. Si vous insistez pour utiliser find avec xargs, utilisez-print0
et-0
.i
: Ignorez les distinctions de casse dans le MOTIF et les fichiers d'entrée.n
: Préfixez chaque ligne de sortie avec le numéro de ligne basé sur 1 dans son fichier d'entrée.s
: Supprime les messages d'erreur concernant les fichiers inexistants ou illisibles.r
: Lire tous les fichiers sous chaque répertoire, récursivement.la source
Il y a un nouvel utilitaire appelé The Silversearcher
Il fonctionne en étroite collaboration avec Git et d'autres VCS. Vous n'aurez donc rien dans un .git ou un autre répertoire.
Vous pouvez simplement utiliser
Et il fera le travail pour vous!
la source
Si vous utilisez find like dans votre exemple, il vaut mieux ajouter
-s
(--no-messages
) àgrep
et2>/dev/null
à la fin de la commande pour éviter de nombreux messages d' autorisation refusée émis pargrep
etfind
:find est l'outil standard pour rechercher des fichiers - combiné avec grep lors de la recherche de texte spécifique - sur des plateformes de type Unix. Lacommande find est souvent combinée avec xargs , soit dit en passant.
Des outils plus rapides et plus faciles existent dans le même but - voir ci-dessous. Mieux vaut les essayer, à condition qu'ils soient disponibles sur votre plateforme , bien sûr:
Des alternatives plus rapides et plus faciles
RipGrep - l'outil de recherche le plus rapide:
The Silver Searcher :
ack :
Remarque: Vous pouvez également ajouter
2>/dev/null
à ces commandes pour masquer de nombreux messages d'erreur.Attention : à moins que vous ne puissiez vraiment pas l'éviter, ne cherchez pas dans '/' (le répertoire racine) pour éviter une recherche longue et inefficace! Donc, dans les exemples ci-dessus, vous feriez mieux de remplacer ' / ' par un nom de sous-répertoire, par exemple "/ home" selon l'endroit où vous voulez réellement rechercher ...
la source
grep
find
ne recherche pas directement le texte à l'intérieur des fichiers. Et peut-être que ces outils supplémentaires sont utiles pour certains, mais les anciens temporisateurs et ceux qui sont bien habitués, par exemplegrep
, ne leur donneraient pas du tout de temps (enfin je ne le ferai certainement pas). Mais je ne dis pas qu'ils sont inutiles.fol
? Non bien sûr que non; il a été appelédir
(et je crois qu'il l'est toujours). Le dossier est une chose conçue pour (je suppose) la convivialité, bien que dans ce cas, il soit peut-être stupide pour les utilisateurs moins «avancés»?Essayer:
la source
xargs
comme ça .. considérez ceci.echo "file bar.txt has bar" > bar.txt; echo "file foo bar.txt has foo bar" > "foo bar.txt"; echo "You should never see this foo" > foo; find . -name "*.txt" | xargs grep -i foo # ./foo:You should never see this foo
. L'xargs
ici correspondait au fichier FAUX et ne correspondait PAS au fichier prévu. Soit utiliser unfind .. -print0 | xargs -0 ...
mais c'est une utilisation inutile d'un tuyau ou mieuxfind ... -exec grep ... {} +
Utilisez
pwd
pour rechercher à partir de n'importe quel répertoire dans lequel vous vous trouvez, en recursant vers le basMise à jour Selon la version de grep que vous utilisez, vous pouvez omettre
pwd
. Sur les versions plus récentes,.
semble être le cas par défaut pour grep si aucun répertoire n'est donné ainsi:grep -rnw -e "pattern"
ou
grep -rnw "pattern"
fera la même chose que ci-dessus!
la source
pwd
n'est pas nécessaire du tout, car c'est la valeur par défaut.grep -rnw "pattern"
suffit.grep -rnw
et similaire est ce qui a été répondu comme il y a trois ans, je ne vois pas comment cette réponse ajoute de la valeur.grep -rnw '/path/to/somewhere/' -e "pattern"
ce que vous avez ici. 5 votes après 2,3 millions de visites ne signifient pas grand-chose.grep
peut être utilisé même si nous ne recherchons pas de chaîne.Tout simplement en cours d'exécution,
imprimera le chemin d'accès à tous les fichiers texte, c'est-à-dire ceux contenant uniquement des caractères imprimables.
la source
ls
oufind
(pour le récursif)Voici la liste de plusieurs commandes qui peuvent être utilisées pour rechercher un fichier.
la source
egrep
est équivalent àgrep -E
et cela signifie que--extended-regexp
vous pouvez trouver des détails ici unix.stackexchange.com/a/17951/196072Silver Searcher est un outil formidable, mais ripgrep peut être encore meilleur.
Il fonctionne sur Linux, Mac et Windows, et a été écrit sur Hacker News il y a quelques mois (cela a un lien vers le blog d'Andrew Gallant qui a un lien GitHub):
Ripgrep - Un nouvel outil de recherche en ligne de commande
la source
Explication des commentaires
find est une commande qui vous permet de rechercher des fichiers et d'autres objets tels que des répertoires et des liens dans des sous-répertoires d'un chemin donné. Si vous ne spécifiez pas de masque que les noms de fichiers doivent respecter, il énumère tous les objets de répertoire.
la source
Essayer:
qui va rechercher tous les systèmes de fichiers, car
/
s'agit du dossier racine.Pour l'utilisation du dossier de départ:
Pour l'utilisation du dossier actuel:
la source
J'espère que cela vous sera utile ...
Développer
grep
un peu pour donner plus d'informations dans la sortie, par exemple, pour obtenir le numéro de ligne dans le fichier où se trouve le texte, peut se faire comme suit:Et si vous avez une idée du type de fichier, vous pouvez affiner votre recherche en spécifiant les extensions de type de fichier à rechercher, dans ce cas
.pas
OU les.dfm
fichiers:Brève explication des options:
.
dans lefind
spécifie du répertoire en cours.-name
"*.*
": Pour tous les fichiers (-name "*.pas
" -o "-name*.dfm
"): Seuls les*.pas
OR*.dfm
fichiers, ou spécifiés avec-o
-type f
spécifie que vous recherchez des fichiers-print0
et--null
de l'autre côté du|
(pipe) sont les plus cruciaux, en passant le nom de fichier defind
à l'grep
incrusté dans lexargs
, permettant le passage de noms de fichiers AVEC des espaces dans les noms de fichiers, permettant à grep de traiter le chemin et le nom de fichier comme une chaîne, et ne pas le briser sur chaque espace.la source
-name '*.*'
n'est pas ce que vous dites; il ne reprendrait pas un fichier appelé «fichier» car le motif ne correspond pas à cela (pas de .ext);*
serait cependant (bien. fichiers de côté). Mais il y a une autre chose: si vous voulez tous les fichiers, pourquoi prendre la peine de spécifier un nom de fichier en premier lieu? Aucun autre commentaire - sauf qu'il est bon de savoir qu'il y a encore des gens qui n'utilisent pas le «dossier» de la terminologie MS (ce qui, après l'avoir suffisamment dit, je ne l'ajouterais pas, mais je voulais souligner la déclaration légèrement incorrecte que vous avez faite avec les noms de fichiers - ainsi que la redondance / l'inutilité dans le cas de «tous»).Un simple
find
peut fonctionner à portée de main. alias dans votre~/.bashrc
fichier:Démarrez un nouveau terminal et lancez:
la source
J'ai écrit un script Python qui fait quelque chose de similaire. C'est ainsi qu'il faut utiliser ce script.
Le premier argument,,
path
est le répertoire dans lequel nous allons effectuer une recherche récursive. Le deuxième argument,,pattern_to_search
est une expression régulière que nous voulons rechercher dans un fichier. Nous utilisons le format d'expression régulière défini dans la bibliothèque Pythonre
. Dans ce script, le.
correspond également à la nouvelle ligne.Le troisième argument
file_pattern
,, est facultatif. Il s'agit d'une autre expression régulière qui fonctionne sur un nom de fichier. Seuls les fichiers correspondant à cette expression régulière seront pris en compte.Par exemple, si je veux rechercher des fichiers Python avec l'extension
py
contenantPool(
suivie d'un motAdaptor
, je fais ce qui suit,Et le tour est joué, il génère le chemin des fichiers correspondants et le numéro de ligne sur lequel la correspondance a été trouvée. Si plusieurs correspondances ont été trouvées, chaque numéro de ligne sera ajouté au nom de fichier.
la source
Si vous souhaitez strictement utiliser,
find
utilisezfind + grep
:find /path/to/somewhere/ -type f -exec grep -nw 'textPattern' {} \;
pas:
1.Utilisez
find
pour rechercher des fichiers,2.Ensuite, exécutez-les
grep
sur tous.Cela peut vous permettre de
find
rechercher des fichiers.Utilisez
-name Pattern
si vous souhaitezgrep
uniquement certains fichiers:find /path/to/somewhere/ -type f -name \*.cpp -exec grep -nw 'textPattern' {} \;
Vous pouvez jouer avec et utiliser différentes options
find
pour améliorer ou affiner votre recherche de fichiers.la source
Utilisation:
Cela indiquera le nombre de copies de votre modèle dans chacun des fichiers du répertoire actuel.
la source
grep est votre bon ami pour y parvenir.
Si vous ne vous souciez pas de la casse du texte à rechercher, utilisez:
la source
-
s dans la chaîne de recherche, vous voudrez d'abord passer--
à grep; cela peut provoquer des effets secondaires intéressants sinon!Je suis fasciné par la simplicité de grep avec 'rl':
Cela fonctionne tout simplement parfait ...
la source
.txt
). Ou existe-t-il un moyen de le faire?Pour rechercher la chaîne et produire uniquement cette ligne avec la chaîne de recherche:
par exemple:
Pour afficher le nom de fichier contenant la chaîne de recherche:
par exemple:
la source
find … -exec grep 'str' {} \;
(si vous devez utiliserfind
du tout).find
espaces contenus .. vous pourriez finir pargrepping
les mauvais fichiers et / ou manquer les bons fichiers. Utilisez simplementfind ... -exec grep ...
si vous avez besoin d'utiliserfind
.. mais dans ce cas, ungrep -r ...
suffit.Il existe un
ack
outil qui ferait exactement ce que vous recherchez.http://linux.die.net/man/1/ack
Vous pouvez ignorer la
-i
recherche sensible à la cassela source
Toutes les réponses précédentes suggèrent grep et find. Mais il existe un autre moyen: utiliser Midnight Commander
C'est un utilitaire gratuit (30 ans, prouvé par le temps) qui est visuel sans être GUI. Il a des tonnes de fonctions et la recherche de fichiers n'est que l'une d'entre elles.
la source
La commande ci-dessous fonctionnera bien pour cette approche:
la source
find
puisgrep -r
? Ils sont destinés à la même chose, donc c'est redondant.find
.Évitez les tracas et installez ack-grep. Il élimine beaucoup de problèmes d'autorisation et de devis.
Ensuite, allez dans le répertoire que vous souhaitez rechercher et exécutez la commande ci-dessous
la source