Rechercher tous les fichiers dont le nom contient une chaîne

177

J'ai recherché une commande qui renverra des fichiers du répertoire actuel contenant une chaîne dans le nom de fichier. Je l' ai vu locateet les findcommandes qui peuvent trouver les fichiers commençant par quelque chose first_word*ou se terminant par quelque chose *.jpg.

Comment puis-je renvoyer une liste de fichiers contenant une chaîne dans le nom de fichier?

Par exemple, si 2012-06-04-touch-multiple-files-in-linux.markdownétait un fichier dans le répertoire courant.

Comment pourrais-je retourner ce fichier et d'autres contenant la chaîne touch? En utilisant une commande telle quefind '/touch/'

Dru
la source
la question prête à confusion. voulez-vous rechercher des fichiers contenant une chaîne ou des fichiers dont les noms contiennent cette chaîne? la première question réponse avec man grep, la seconde avec man find. pourquoi voulez-vous google au lieu d'utiliser l'homme, je ne sais pas.
juste quelqu'un
1
Merci! La première phrase ne précisait pas s'il s'agissait du contenu du fichier ou d'un nom de fichier. Actualisé.
Dru

Réponses:

304

Utilisez find:

find . -maxdepth 1 -name "*string*" -print

Il trouvera tous les fichiers dans le répertoire courant (supprimez maxdepth 1si vous le souhaitez récursif) contenant "string" et l'imprimera à l'écran.

Si vous voulez éviter le fichier contenant ':', vous pouvez taper:

find . -maxdepth 1 -name "*string*" ! -name "*:*" -print

Si vous souhaitez utiliser grep(mais je pense que ce n'est pas nécessaire dans la mesure où vous ne souhaitez pas vérifier le contenu du fichier), vous pouvez utiliser:

ls | grep touch

Mais, je le répète, findc'est une solution meilleure et plus propre pour votre tâche.

Zagorax
la source
Merci @Zagorax. Cela le fait exactement. Je souhaite que la commande ne soit pas si longue mais ayee :)
Dru
2
@Dru, Modifié pour couvrir le cas si vous voulez éviter les deux points. findest un outil très puissant, il doit être en quelque sorte «long». :)
Zagorax
Merci le premier l'a fait parfaitement sans renvoyer aucun contenu.
Dru
3
@Dru, si vous voulez qu'il soit `` plus court '', vous pouvez éviter -printcar c'est le comportement par défaut et .comme c'est le dossier par défaut où il vérifie.
Zagorax
1
find . -name "*string*"Fonctionne très bien aussi. La suppression .jette une erreur de ma part. Merci encore @Zagorax.
Dru
14

Utilisez grep comme suit:

grep -R "touch" .

-Rsignifie récurer. Si vous préférez ne pas aller dans les sous-répertoires, ignorez-le.

-isignifie "ignorer la casse". Cela vaut peut-être la peine d'être essayé.

carlspring
la source
Génial. J'ai remarqué que certains contenus de fichiers suivent un :. Y a-t-il un moyen de retenir cela? Vous utilisez une option peut-être?
Dru
1
Essayez:grep -R "touch" . | cut -d ":" -f 2
carlspring
Cela semble ne produire que le contenu des fichiers. Vous avez essentiellement répondu à ma question, je peux essayer de creuser pour retenir le contenu.
Dru
Ah ... vous n'avez besoin que des noms de fichiers? Exécuter: grep -R "touch" . | cut -d ":" -f 1 (désolé doit vous avoir mal lu).
carlspring
Merci @carlspring, c'est intéressant. grepretourne des fichiers avec le contenu et les noms de fichiers contenant touchou le contenu contenant touch, je ne sais pas encore ce qui est le cas. De la liste des fichiers renvoyés, la moitié contient touchdans le titre et l'autre moitié touchdans le corps, pas le titre. Je viens de m'en rendre compte.
Dru
5

L' -maxdepthoption doit être avant l' -nameoption, comme ci-dessous.,

find . -maxdepth 1 -name "string" -print
Sunil Dias
la source
1
Vous devez mettre * avant et après la "chaîne".
Aerin
3
find $HOME -name "hello.c" -print

Cela recherchera dans tout le système $HOME(c'est-à-dire /home/username/) tous les fichiers nommés «hello.c» et affichera leurs chemins:

/Users/user/Downloads/hello.c
/Users/user/hello.c

Cependant, il ne correspondra pas HELLO.Cou HellO.C. Pour faire correspondre est insensible à la casse, passez l' -inameoption comme suit:

find $HOME -iname "hello.c" -print

Exemples de sorties:

/Users/user/Downloads/hello.c
/Users/user/Downloads/Y/Hello.C
/Users/user/Downloads/Z/HELLO.c
/Users/user/hello.c

Passez l' -type foption pour rechercher uniquement les fichiers:

find /dir/to/search -type f -iname "fooBar.conf.sample" -print
find $HOME -type f -iname "fooBar.conf.sample" -print

Cela -inamefonctionne sur la commande de recherche de version GNU ou BSD (y compris OS X). Si votre version de la commande find ne prend pas en charge -iname, essayez la syntaxe suivante à l'aide de la grepcommande:

find $HOME | grep -i "hello.c"
find $HOME -name "*" -print | grep -i "hello.c"

OU essayez

find $HOME -name '[hH][eE][lL][lL][oO].[cC]' -print

Exemples de sorties:

/Users/user/Downloads/Z/HELLO.C
/Users/user/Downloads/Z/HEllO.c
/Users/user/Downloads/hello.c
/Users/user/hello.c
Shilovk
la source
0

Si la chaîne est au début du nom, vous pouvez le faire

$ compgen -f .bash
.bashrc
.bash_profile
.bash_prompt
Steven Penny
la source
3
compgenn'est pas un marteau approprié pour ce clou. Cet outil peu utilisé est conçu pour lister les commandes disponibles , et en tant que tel, il répertorie les fichiers dans le répertoire courant (qui pourraient être des scripts) et il ne peut ni récurer ni regarder au-delà du début d'un nom de fichier ni rechercher le contenu d'un fichier, ce qui le rend surtout inutile.
msanford
0

Une alternative aux nombreuses solutions déjà proposées consiste à utiliser le glob **. Lorsque vous utilisez bashavec l'option globstar( shopt -s globstar) ou que vous utilisez zsh, vous pouvez simplement utiliser le glob **pour cela.

**/bar

effectue une recherche récursive dans le répertoire des fichiers nommés bar(y compris potentiellement le fichier bardans le répertoire courant). Remarquez que cela ne peut pas être combiné avec d'autres formes de globbing dans le même segment de chemin; dans ce cas, les *opérateurs reviennent à leur effet habituel.

Notez qu'il existe une différence subtile entre zshet bashici. Tandis que bashtraversera les liens souples vers les répertoires, zshnon. Pour cela, vous devez utiliser le glob ***/in zsh.

kvantour
la source
0
find / -exec grep -lR "{test-string}" {} \;
Shahid
la source
1
Cette réponse a été signalée comme étant de mauvaise qualité. Veuillez expliquer ce que font vos modifications proposées.
Miroslav Glamuzina
-2
grep -R "somestring" | cut -d ":" -f 1
Saurabh kukade
la source
2
Cela semble être une réponse à une question différente - mais comme vous n'avez fourni aucune explication, cela n'est pas évident pour le demandeur ou pour quiconque.
Toby Speight