Visualizza il nome del file prima della riga corrispondente


282

Come posso grepvisualizzare il nome del file prima delle righe corrispondenti nel suo output?


2
per favore dimmi la tua versione grepgrep --version
Kent

3
Kent, grep --versionè quel comando da usare per conoscere la versione grep? In tal caso, non funziona. Impossibile trovare altri comandi per conoscere la versione di grep.
Vivek,

2
bella domanda, ma "versione Os" è un esempio di file confuso
HaveAGuess

1
Il sistema operativo e la versione sono irrilevanti qui.
MD XF,

grep 'pattern' *
user0

Risposte:


431

Prova questo piccolo trucco per convincerti grepa pensare che si tratti di più file, in modo da visualizzare il nome file:

grep 'pattern' file /dev/null

Per ottenere anche il numero di riga:

grep -n 'pattern' file /dev/null

6
Sì, ha funzionato. Potete per favore dirmi qual è il significato di aggiungere /dev/nullin questo comando?
Vivek,

55
Se grepviene fornito con più nomi di file, visualizzerà automaticamente i nomi dei file prima della corrispondenza, ma lascerà il nome del file fuori nel caso di un singolo file di input. Usando /dev/nullcome file di input aggiuntivo grep"pensa" che abbia a che fare con più file, ma / dev / null è ovviamente vuoto, quindi non verrà visualizzato nell'elenco delle corrispondenze ..
Scrutinizer

32
usare / dev / null è un trucco intelligente, ma penso che il suggerimento sotto il flag -H sia una risposta migliore.
JohnQ,

22
OK, ma l' -Hopzione per grep non fa parte di POSIX e il sistema operativo utilizzato è Solaris 10, dove né grep standard né la versione conforme a POSIX di grep hanno l' -Hopzione.
Scrutinizer

4
Questo è importante se stai usando grep con find, come find . -name foo -exec grep pattern {} \;- supponendo che un sacco di file nominati foonella tua sottodirectory, passi findancora grepun singolo file su cui operare alla volta. Il /dev/nulltrucco sembra funzionare in tutti i gusti Linux / OSX che ho provato, quindi complimenti! Nota Penso che -Hsia più pulito, ma come indicato di seguito, potrebbe non essere supportato con la tua versione di grep.
Jon V,

297

Se hai le opzioni -He -ndisponibili ( man grepè tuo amico):

$ cat file
foo
bar
foobar

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

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

Opzioni:

-H, --with-nomefile

Stampa il nome del file per ogni corrispondenza. Questo è il valore predefinito quando c'è più di un file da cercare.

-n, --line-number

Prefisso ogni riga di output con il numero di riga in base 1 all'interno del suo file di input. (-n è specificato da POSIX.)

-Hè un'estensione GNU, ma -nè specificata da POSIX


3
No, -Hnon è supportato qui.
Vivek,

1
Supportato ma fornisce sempre grep: file: nessun file o directory
simile

2
funziona su Ubuntu -H e -n. Probabilmente con tutte le versioni più recenti di * nix
tgkprog

1
Ho lottato con questo per anni senza sera pensando che ci fossero queste opzioni!
GreenSaguaro,

46

Nessun trucco necessario.

grep --with-filename 'pattern' file

Con i numeri di riga:

grep -n --with-filename 'pattern' file

3
@codeforester Non conosco nessun altro grep, quindi non lo so.
MD XF,

2
Freddo ! questo ha funzionato per Linux. se usi mac, puoi installare coreutils con brew. E ricorda di aggiungere PATH = "/ usr / local / opt / coreutils / libexec / gnubin: $ PATH" al tuo .bashrc
zw963

2
Questo (anche) ha funzionato in MinGW (1.0.17, credo).
Peter Mortensen,

Funziona per me con il Mac grep integrato (2.5.1-FreeBSD). Ma per usare il grep alternativo di Homebrew, un altro modo è quello di eseguire brew install grepe poi semplicemente usare ggrep. Non è necessario modificare il PERCORSO.
wonderlr,

5

Che ne dici di questo, che sono riuscito a ottenere grazie, in parte, a questo post.

Volete trovare diversi file, diciamo registri con nomi diversi ma con un modello (ad esempio filename=logfile.DATE), all'interno di diverse directory con un modello (ad esempio /logsapp1, /logsapp2). Ogni file ha un modello che vuoi grep (ad esempio "init time") e vuoi avere il "init time"file di ogni file, ma sapendo a quale file appartiene.

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

Quindi outputfilename.txtsarebbe qualcosa di simile

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

In generale

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

Spiegazione:

find il comando cercherà i nomi dei file in base al modello

quindi, pipe xargs -I{}reindirizzerà l' findoutput su{}

quale sarà l'input per grep ""pattern" {}

Quindi il trucco per far grepvisualizzare i nomi dei file\dev\null

e infine, scrivere l'output nel file con tee outputfile.txt

Questo ha funzionato per me nella grepversione 9.0.5 build 1989.


3
O semplicemente usando findfind ./path_pattern/to_files -type f -name "files*.log" -exec grep -Hn pattern {} \;
Martin

1

Questa è una leggera modifica rispetto a una soluzione precedente. Il mio esempio cerca il reindirizzamento stderr negli script bash: grep '2>' $(find . -name "*.bash")


-7
grep 'search this' *.txt

ha funzionato per me per cercare tra tutti i file .txt (inserisci il tuo valore di ricerca, ovviamente).

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.