web-dev-qa-db-fra.com

Afficher le nom du fichier avant la ligne correspondante

Comment puis-je obtenir que grep affiche le nom du fichier avant les lignes correspondantes dans sa sortie?

249
Vivek

Essayez cette astuce pour convaincre grep de penser qu'il s'agit de plusieurs fichiers, de sorte qu'il affiche le nom du fichier:

grep 'pattern' file /dev/null

Pour obtenir également le numéro de ligne:

grep -n 'pattern' file /dev/null
395
Scrutinizer

Si vous avez les options -H et -n disponibles (man grep est 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

Les options:

-H, --with-filename

Imprimez le nom du fichier pour chaque correspondance. C'est la valeur par défaut lorsqu'il y a plus d'un fichier à rechercher.

-n, --line-number

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

-H est une extension GNU, mais -n est spécifié par POSIX

266
Chris Seymour

Aucune astuce nécessaire.

grep --with-filename 'pattern' file

Avec numéros de ligne:

grep -n --with-filename 'pattern' file
43
MD XF

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

Vous voulez trouver plusieurs fichiers, disons des journaux avec des noms différents mais un motif (par exemple filename=logfile.DATE), dans plusieurs répertoires avec un motif (par exemple /logsapp1, /logsapp2). Chaque fichier a un motif que vous voulez grep (par exemple "init time") et vous voulez avoir le "init time" 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 le outputfilename.txt serait 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:

La commande find recherchera les noms de fichiers basés sur le motif

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

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

Puis, astuce pour que grep affiche les noms de fichiers \dev\null

et finalement, écrivez la sortie dans le fichier avec tee outputfile.txt

Cela a fonctionné pour moi dans grep version 9.0.5 build 1989.

5
Lejuanjowski

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

1
Richard Jessop