Afficher le nom de fichier avant de faire correspondre la ligne

282

Comment grepafficher le nom de fichier avant les lignes correspondantes dans sa sortie?

Vivek
la source
2
pls dire à votre version grepgrep --version
Kent
3
kent, grep --versionest-ce la commande à utiliser pour connaître la version grep? Si c'est le cas, cela ne fonctionne pas. Impossible de trouver une autre commande pour connaître la version grep.
Vivek
2
bonne question mais «Os version» est un exemple de nom de fichier déroutant
HaveAGuess
1
L'OS et la version ne sont pas pertinents ici.
MD XF
grep 'pattern' *
user0

Réponses:

431

Essayez cette petite astuce pour vous grepfaire croire qu'elle traite plusieurs fichiers, afin qu'elle affiche le nom de fichier:

grep 'pattern' file /dev/null

Pour obtenir également le numéro de ligne:

grep -n 'pattern' file /dev/null
Scrutinisateur
la source
6
Oui, ça a marché. Pouvez-vous me dire quelle est la signification de l'ajout /dev/nullde cette commande?
Vivek
55
S'il grepest fourni avec plusieurs noms de fichier, il affichera automatiquement les noms de fichier avant la correspondance, mais il laissera le nom de fichier en cas de fichier d'entrée unique. En utilisant /dev/nullcomme fichier d'entrée supplémentaire grep"pense" qu'il traite de plusieurs fichiers, mais / dev / null est bien sûr vide, donc il n'apparaîtra pas dans la liste des correspondances ..
Scrutinizer
32
utiliser / dev / null est une astuce intelligente, mais je pense que la suggestion ci-dessous du drapeau -H est une meilleure réponse.
JohnQ
22
OK, mais l' -Hoption pour grep ne fait pas partie de POSIX, et le système d'exploitation utilisé est Solaris 10, où ni le grep standard, ni la version conforme à POSIX de grep n'ont l' -Hoption.
Scrutinizer
4
C'est important si vous utilisez grep avec find, comme find . -name foo -exec grep pattern {} \;- en supposant que beaucoup de fichiers sont nommés foodans votre sous-répertoire, findremet toujours grepun seul fichier pour fonctionner à la fois. L' /dev/nullastuce semble fonctionner dans toutes les saveurs linux / osx que j'ai essayées, alors bravo! Notez que je pense que -Hc'est plus propre, mais comme mentionné ci-dessous, il pourrait ne pas être pris en charge avec votre version de grep.
Jon V
297

Si vous avez les options -Het -ndisponibles ( man grepest votre ami):

$ cat file
foo
bar
foobar

$ grep -H foo file
file:foo
file:foobar

$ grep -Hn foo file
file:1:foo
file:3:foobar

Options:

-H, --with-filename

Imprimez le nom du fichier pour chaque correspondance. Il s'agit de la valeur par défaut lorsqu'il y a plusieurs fichiers à rechercher.

-n, - numéro-ligne

Préfixez chaque ligne de sortie avec le numéro de ligne 1 dans son fichier d'entrée. (-n est spécifié par POSIX.)

-Hest une extension GNU, mais -nest spécifiée par POSIX

Chris Seymour
la source
3
Non, -Hn'est pas pris en charge ici.
Vivek
1
Pris en charge, mais il donne toujours grep: file: Aucun fichier ou répertoire de ce type
pal4life
2
fonctionne sur ubuntu -H et -n. Probablement avec toutes les nouvelles versions de * nix
tgkprog
1
J'ai lutté avec ça pendant des années sans penser le soir qu'il y avait ces options!
GreenSaguaro
46

Aucune astuce nécessaire.

grep --with-filename 'pattern' file

Avec des numéros de ligne:

grep -n --with-filename 'pattern' file
MD XF
la source
3
@codeforester Je ne connais aucun autre greps, donc je ne sais pas.
MD XF
2
Cool ! cela a fonctionné pour linux. si vous utilisez mac, pouvez installer coreutils avec brew. Et n'oubliez pas d'ajouter PATH = "/ usr / local / opt / coreutils / libexec / gnubin: $ PATH" à la vôtre .bashrc
zw963
2
Cela (aussi) a fonctionné dans MinGW (1.0.17, je pense).
Peter Mortensen
Cela fonctionne pour moi avec le grep Mac intégré (2.5.1-FreeBSD). Mais pour utiliser l'alternative grep de Homebrew, une autre façon est d'exécuter brew install greppuis d'utiliser ggrep. Pas besoin de modifier PATH.
wonderlr
5

Que diriez-vous de cela, que j'ai réussi à atteindre grâce, en partie, à ce poste.

Vous voulez trouver plusieurs fichiers, disons des journaux avec des noms différents mais un modèle (par exemple filename=logfile.DATE), à l'intérieur de plusieurs répertoires avec un modèle (par exemple /logsapp1, /logsapp2). Chaque fichier a un modèle que vous voulez grep (par exemple "init time"), et vous voulez avoir le "init time"fichier de chaque fichier, mais en sachant à quel fichier il appartient.

find ./logsapp* -name logfile* | xargs -I{} grep "init time" {} \dev\null | tee outputfilename.txt

Alors ce outputfilename.txtserait quelque chose comme

./logsapp1/logfile.22102015: init time: 10ms
./logsapp1/logfile.21102015: init time: 15ms
./logsapp2/logfile.21102015: init time: 17ms
./logsapp2/logfile.22102015: init time: 11ms

En général

find ./path_pattern/to_files* -name filename_pattern* | xargs -I{} grep "grep_pattern" {} \dev\null | tee outfilename.txt

Explication:

find La commande recherchera les noms de fichiers en fonction du modèle

puis, le tube xargs -I{}redirigera la findsortie vers le{}

qui sera l'entrée pour grep ""pattern" {}

Ensuite, l'astuce pour faire grepafficher les noms de fichiers\dev\null

et enfin, écrivez la sortie dans un fichier avec tee outputfile.txt

Cela a fonctionné pour moi dans la grepversion 9.0.5 build 1989.

Lejuanjowski
la source
3
Ou tout simplement en utilisant findfind ./path_pattern/to_files -type f -name "files*.log" -exec grep -Hn pattern {} \;
Martin
1

Il s'agit d'une légère modification par rapport à une solution précédente. Mon exemple recherche la redirection stderr dans les scripts bash: grep '2>' $(find . -name "*.bash")

Richard Jessop
la source
-7
grep 'search this' *.txt

travaillé pour moi pour rechercher dans tous les fichiers .txt (entrez votre propre valeur de recherche, bien sûr).

MagicMojo
la source