Comment «grep» pour un nom de fichier au lieu du contenu d'un fichier?

135

grep est utilisé pour rechercher dans un fichier pour voir si une ligne correspond à une expression régulière donnée. Cependant, j'ai cette situation - je veux écrire une expression régulière qui correspondra au nom de fichier lui-même (et non au contenu du fichier). Je vais l'exécuter à partir du répertoire racine du système, pour trouver tous les fichiers qui correspondent à l'expression régulière.

Par exemple, si je veux trouver tous les fichiers de formulaire VB qui commencent par un "f" et se terminent par .frm, j'utiliserai l'expression régulière -

   "f[[:alnum:]]*\.frm"

Grep peut-il faire cela? Sinon, existe-t-il un utilitaire qui me permettrait de le faire? Merci.

Code bleu
la source

Réponses:

120

Vous devez utiliser à la findplace de grepdans ce cas.

Vous pouvez également utiliser finden combinaison avec grepou egrep:

$ find | grep "f[[:alnum:]]\.frm"
Pablo Santa Cruz
la source
12
Ceci est inutile. Find a cette fonctionnalité intégrée avec l' -regexoption.
whereswalden
4
c'est inutile ici, mais grep supporte perl regex alors que find ne le fait pas.
Dan
2
Non, vous pouvez utiliser grep. Bien plus facile que d'utiliser find. Ajoutez le commutateur "-rl" et il recherchera le nom de fichier au lieu du fichier. Voir mon message ci-dessous.
RM
@ alpha_989, j'ai dit que grep le supportait, ce qu'il fait: gnu.org/software/grep/manual/html_node / ... point est le piping vers grep n'est nécessaire que si vous avez besoin de pcre. whereswalden a la bonne réponse
Dan
60

Exemple

find <path> -name *FileName*

Du manuel:

modèle de recherche-nom

La base du nom de fichier (le chemin avec les principaux répertoires supprimés) correspond au modèle de modèle de shell. Comme les principaux répertoires sont supprimés, les noms de fichiers pris en compte pour une correspondance avec -name n'incluront jamais de barre oblique, donc "-name a / b" ne correspondra jamais à rien (vous devrez probablement utiliser -path à la place). Les métacaractères ("*", "?" Et "[]") correspondent à un "." au début du nom de base (il s'agit d'un changement dans find utils-4.2.2; voir la section CONFORMITÉ AUX NORMES ci-dessous). Pour ignorer un répertoire et les fichiers qu'il contient, utilisez -prune; voir un exemple dans la description de -path. Les accolades ne sont pas reconnues comme étant spéciales, malgré le fait que certaines coquilles, y compris Bash, imprègnent les accolades d'une signification particulière dans les motifs de coquille. La correspondance de nom de fichier est effectuée à l'aide de la fonction de bibliothèque fnmatch (3). N'oubliez pas de mettre le motif entre guillemets afin de le protéger de l'expansion par le shell.

javaPlease42
la source
2
J'ai trouvé cette réponse la plus utile. J'ai ajouté quelques options supplémentaires: find . -maxdepth 1 -name "*filename*" -print
JSON C11
47

Comme l'a dit Pablo, vous devez utiliser à la findplace de grep, mais il n'est pas nécessaire de diriger findvers grep. finda cette fonctionnalité intégrée:

find . -regex 'f[[:alnum:]]\.frm'

findest un programme très puissant pour rechercher des fichiers par nom et prend en charge la recherche par type de fichier, la limitation de la profondeur, la combinaison de différents termes de recherche avec des opérations booléennes et l'exécution de commandes arbitraires sur les fichiers trouvés. Consultez la page de manuel find pour plus d'informations.

whereswalden
la source
1
J'ajouterais la fonction très pratique de trouver pour rechercher par date avec -mtimeet-mmin
Johnride
1
De plus, le commutateur -regex effectue des correspondances avec le chemin complet. Donc, pour fonctionner, l'exemple doit ajouter. * Au début de l'expression régulière.
tumasgiu
15

Vous pouvez trouver le chemin complet d'un fichier en utilisant grep, il suffit de diriger la sortie de l'arbre

tree -f | grep filename

Voici une fonction que vous pouvez mettre dans votre .bash_profile ou .bashrc

findfile(){ tree -f | grep $1; } # $1 = filename, -f is full path
Jasonleonhard
la source
-f est facultatif.
jasonleonhard
10
find -iname "file_name"

Syntax :-
find -type type_descriptor file_name_here

types_descriptor types: -

f: fichier régulier

d: répertoire

l: lien symbolique

c: périphériques de caractères

b: bloquer les périphériques

Sireesh Yarlagadda
la source
1
Je n'arrive pas à utiliser un nom de fichier suivant le -type typedescriptorseul. Est-ce une erreur?
Allan Nørgaard
5

Vous pouvez également faire:

tree | grep filename

Cela dirige la sortie de la commande tree vers grep pour une recherche. Cela vous dira seulement si le fichier existe.

caylus
la source
1

Non, grep fonctionne très bien pour cela:

 grep -rl "filename" [starting point]

 grep -rL "not in filename"
RM
la source
1
Cela recherche le contenu du fichier pour "nom de fichier", puis imprime les noms des fichiers avec des correspondances. OP veut que les noms de fichiers correspondent, pas le contenu des fichiers.
Matthew
1
D'accord, cela ne recherche pas les noms de fichiers, il imprime simplement les noms des noms de fichiers pour lesquels il a trouvé des correspondances de contenu . Vous avez considérablement mal compris les options -let -L.
Prometheus
2
+1 pour être exactement ce dont j'ai besoin. Heureux de ne pas avoir à critiquer la question pour trouver la réponse dont j'avais besoin
Alexander McNulty
-1

Aussi pour plusieurs fichiers.

tree /path/to/directory/ | grep -i "file1 \| file2 \| file3"
DimiDak
la source
-1

Le moyen le plus simple est

find . | grep test

ici find listera tous les fichiers dans le répertoire courant (.) ie, récursivement. Et puis ce n'est qu'un simple grep. tous les fichiers dont le nom a "test" apparaîtront.

vous pouvez jouer avec grep selon vos besoins. Remarque: comme le grep est une classification de chaîne générique, cela peut avoir pour résultat de vous donner non seulement des noms de fichiers. mais si un chemin a un répertoire ('/xyz_test_123/other.txt') viendrait également au jeu de résultats. à votre santé

sachyy
la source
Cela trouvera n'importe quoi avec "test" dans le chemin, par exemple ./foo/bar/latest/fred.txt.
Paul R
Oh. Celui auquel je n'ai pas pensé. Merci d'avoir mentionné.
sachyy