2013-03-15 8 views
175

Jak mogę uzyskać grep, aby wyświetlić nazwę pliku przed pasującymi wierszami na jego wydruku?Wyświetl nazwę pliku przed dopasowaniem wiersza (grep)

+2

pls poinformować grep wersji 'grep --version' – Kent

+3

Kent,' grep --version' jest to, że komenda do wykorzystania sprawdzić wersję grep? Jeśli tak, to nie działa. Nie mogłem znaleźć żadnego innego polecenia, aby poznać wersję grep. – Vivek

+2

dobre pytanie, ale "wersja Os" jest mylącym przykładem nazwy pliku – HaveAGuess

Odpowiedz

284

Spróbuj mały trick namówić grep do myślenia, że ​​ma do czynienia z wieloma plikami, dzięki czemu wyświetla nazwę pliku:

grep 'pattern' file /dev/null 

Aby uzyskać również numer wiersza:

grep -n 'pattern' file /dev/null 
+3

Tak, zadziałało. Czy możesz mi powiedzieć, jakie jest znaczenie dodania '/ dev/null' w tym poleceniu? – Vivek

+30

Jeśli 'grep' jest dostarczany z wieloma nazwami plików, automatycznie wyświetli nazwy plików przed dopasowaniem, ale pozostawi nazwę pliku w przypadku pojedynczego pliku wejściowego. Używając '/ dev/null' jako dodatkowego pliku wejściowego' grep' "uważa, że" ma do czynienia z wieloma plikami, ale/dev/null jest oczywiście pusty, więc nie pojawi się na liście meczów. – Scrutinizer

+23

używając/dev/null to sprytna sztuczka, ale myślę, że sugestia poniżej flagi -H jest lepszą odpowiedzią. – JohnQ

188

Jeśli dostępne są następujące opcje: -H i -n (man grep):

$ cat file 
foo 
bar 
foobar 

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

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

Opcje:

-H, --with-filename

Drukuj nazwa pliku dla każdego meczu. Jest to ustawienie domyślne, gdy istnieje więcej niż jeden plik do wyszukiwania .

-n, --line numer

Prefiks każda linia wyjścia z linii numer 1 z siedzibą w swoim pliku wejściowego. (-n jest określony przez POSIX.)

-H może być rozszerzenie GNU ale -n jest określony przez POSIX.

+2

Nie, '-H' nie jest tutaj obsługiwane. – Vivek

+1

Obsługiwany, ale zawsze daje grep: file: Brak takiego pliku lub katalogu – pal4life

+2

działa na ubuntu -H i -n. Prawdopodobnie we wszystkich nowszych wersjach * nix – tgkprog

4

Co powiesz na to, co udało mi się osiągnąć dzięki częściowo temu postowi.

Chcesz znaleźć kilka plików, powiedzmy logi o różnych nazwach, ale wzorzec (np. filename=logfile.DATE), wewnątrz kilku katalogów ze wzorem (np. /logsapp1, /logsapp2). Każdy plik ma wzorzec, który chcesz przeskakiwać (na przykład "init time"), a chcesz mieć plik "init time" każdego pliku, ale wiedzący, do którego pliku należy.

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

Następnie outputfilename.txt byłoby coś

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

W ogólnym

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

Objaśnienie:

find polecenie wyszuka nazw opartych na wzór

wtedy, rura xargs -I{} przekieruje wyjście find do {}

który będzie wejście do grep ""pattern" {}

Wtedy podstęp aby grep wyświetlenie nazw \dev\null

i wreszcie napisać wyjście w pliku z tee outputfile.txt

To zadziałało dla mnie w grep wersja 9.0.5 build 1989.

+2

Lub po prostu znajdź' find ./path_pattern/to_files -type f -name "pliki * .log" -exec grep -Hn wzór {} \; ' – Martin

-3
grep 'search this' *.txt 

pracował dla mnie, aby przeszukać wszystkie pliki .txt (oczywiście podaj własną wartość wyszukiwania).

17

Żadna sztuczka nie jest konieczna.

grep --with-filename 'pattern' file 

z numerem linii:

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

To działa tylko w GNU 'grep', prawda? – codeforester

+2

@codeforester Nie znam żadnych innych 'grep's, więc nie wiem. –

+2

Cool! to działało dla systemu Linux. jeśli używasz mac, możesz zainstalować coreutils z naparami. I pamiętaj o dodaniu PATH = "/ usr/local/opt/coreutils/libexec/gnubin: $ PATH" do twojego .bashrc – zw963

0

To nieznaczne zmiany od poprzedniego rozwiązania. Mój przykład wygląda na stderr przekierowania w bashu: grep '2>' $(find . -name "*.bash")