Je veux rechercher une chaîne de texte dans tous les fichiers d'un répertoire (et non dans ses sous-répertoires; je sais que l' -r
option fait cela, mais ce n'est pas ce que je veux).
Fonctionnement
grep "string" /path/to/dir
est censé être en mesure de le faire, j'ai lu, mais cela me donne l'erreur:
grep: dir: est un répertoire
Ensuite, j'ai essayé de courir
grep
sur plusieurs fichiers.grep "string" .bashrc .bash_aliases
fonctionne parfaitement.grep "string" .bash*
fonctionne comme prévu aussi.grep "string" *
me donne les erreurs:grep: data: Is a directory grep: Desktop: Is a directory grep: Documents: Is a directory grep: Downloads: Is a directory ...
Seules les erreurs sont imprimées, je n'ai pas les lignes correspondantes. J'ai essayé d'utiliser l' -s
option, mais en vain.
Alors, mes questions:
Pourquoi ne puis-je pas utiliser
grep
sur un répertoire, comme dans (1), alors que je devrais pouvoir le faire? J'ai vu cela dans de nombreux exemples sur Internet.
Edit : Quand je dis "utiliser grep sur un répertoire", je veux dire "rechercher dans tous les fichiers de ce répertoire à l'exception de ses sous-répertoires". Je crois que c'est ce que fait grep lorsque vous lui passez un répertoire à la place d'un fichier. Suis-je incorrect?Veuillez me donner une explication sur le fonctionnement de
grep
cela qui expliquerait le comportement des commandes dans (2).
Edit : Permettez-moi d'être plus précis. Pourquoi utilise-t-on des caractères génériques pour spécifier plusieurs fichiers dans lesquels rechercher le travail.bash*
et non avec*
ou même./*
?Comment puis-je rechercher tous les fichiers d'un répertoire (et non ses sous-répertoires) en utilisant
grep
?
*
, appelés globbing. Globbing n'inclut pas les noms de fichiers commençant par un point tel.bashrc
que standard. Vous pouvez définir les options du shell pour qu'il inclue ces fichiers, mais vous pouvez vous retrouver dans un désordre si vous ne savez pas ce que vous faites. Un bon guide pour comprendre la globalisation peut être trouvé ici mywiki.wooledge.org/globgrep "string" .bash*
aussi avec .grep "string" * .* 2>/dev/null
ougrep -s "string" * .*
Réponses:
Dans Bash, un glob ne se développera pas en fichiers cachés, donc si vous voulez rechercher tous les fichiers dans un répertoire, vous devez spécifier les fichiers cachés
.*
et non cachés*
.Pour éviter les erreurs "Est un répertoire", vous pouvez utiliser
-d skip
, mais sur mon système, j'obtiens également une erreurgrep: .gvfs: Permission denied
† , donc je suggère d'utiliser-s
, qui masque tous les messages d'erreur.La commande que vous recherchez est donc:
Si vous recherchez des fichiers dans un autre répertoire:
Une autre option consiste à utiliser l'
dotglob
option shell, qui fera qu'un glob inclura des fichiers cachés.Pour les fichiers dans un autre répertoire:
† Quelqu'un a mentionné que je ne devrais pas recevoir cette erreur. Ils ont peut-être raison - j'ai fait un peu de lecture mais je n'ai pas pu en faire des têtes ou des queues moi-même.
la source
*
et.*
?echo * .*
etecho *.*
exécutez dans votre répertoire personnel, et la différence devrait être évidente. Sinon LMK et je vais l'expliquer.echo *
affiche donc les fichiers et dossiersecho *.*
non masqués,echo .*
affiche les fichiers non masqués, affiche tous les fichiers etecho * .*
affiche tous les fichiers et répertoires. Mais pourquoi la raison de l'espace entre les deux dans ce dernier cas? Cela me semble désordonné. N'y a-t-il pas moyen de combiner les deux pour obtenir les mêmes résultats? Ou sinon existe-t-il une explication syntaxique de la raison pour laquelle les deux doivent être séparés ici, ou est-ce* .*
un cas exceptionnel?*
représente tous les fichiers non cachés (c'est-à-dire les noms de fichiers qui ne commencent pas par un point);.*
représente tous les fichiers cachés (c. -à- noms de fichiers qui ne commence par un point); et*.*
représente tous les fichiers non cachés qui contiennent un point. Dansecho * .*
, les deux globes doivent être séparés car ce sont des globes différents: un pour les non cachés, un pour les cachés. Bien que comme je l'ai écrit dans ma réponse, vous pouvez faire*
inclure des fichiers cachés en activant l'dotglob
option shell.*.*
est courante sous Windows (DOS) pour répertorier tous les fichiers, mais sur * nix n'inclura que les fichiers contenant un point, donc cela n'a aucun sens sur * nix. Au lieu de cela, vous utilisez*
pour répertorier tous les fichiers à l'exception des fichiers masqués et.*
pour répertorier les fichiers masqués.Vous avez besoin de l'
-d skip
option ajoutée.Grep recherche à l'intérieur des fichiers. Vous pouvez effectuer une recherche récursive, comme vous l'avez dit, si vous souhaitez rechercher des fichiers à l'intérieur d'un répertoire.
Par défaut, grep lira tous les fichiers et détectera les répertoires. Parce que par défaut, vous n'avez pas défini quoi faire avec les répertoires avec l'
-d
option, cela donne une sortie d'erreur.Rechercher uniquement dans le répertoire parent serait
grep -d skip "string" ./*
la source
man grep
.-d skip
ne fonctionne pas; c'est fondamentalement la même chose que-s
; voir aussi l'édition. (c) Non,grep -d skip "string" ./*
ne fonctionne pas non plus.Les anciens temporisateurs feraient probablement ceci:
la source
find . -type f -exec grep string {} +
?-maxdepth 1
.find . -type f -maxdepth 1 -exec grep string /dev/null {} +
-H
à grep.Reformulation - vous voulez grep les fichiers dans un seul niveau de sous-répertoire, mais pas récursif dans tous les sous-sous-répertoires?
Ou si vous ne voulez pas les fichiers dans le répertoire courant
Notez que cela ne trouvera pas les répertoires commençant par un point.
devrait faire ce travail.
Il existe également des paramètres de restriction
-maxdepth
et-mindepth
disponibles pour lafind
commande.la source
grep forthis */*
rechercherait -il pas des fichiers à la fois dans le répertoire actuel et dans un répertoire vers le bas?*/*
ne fait correspondre les choses qu'avec une seule barre oblique. Si vous aviez un fichier nomméa/b
dans le répertoire courant, alors `* / * correspondrait à cela.Voici un exemple pour ignorer les répertoires sans ignorer toutes les erreurs:
la source