grep plik, ale pokaż kilka otaczających linii?

3414

Chciałbym napisać grepciąg, ale także pokazać poprzednie pięć wierszy i kolejne pięć wierszy, a także dopasowaną linię. Jak mógłbym to zrobić?

Mark Harrison
źródło
3
W tym celu trzymam kopię skryptu Perla Brendana Gregga . Działa dobrze.
Ethan Post,
6
Aby znaleźć rozwiązanie działające w systemie Solaris, sprawdź ten link .
jahroy
106
man grep | grep -C 1 context:)
StvnW
20
man grep | grep -C 1 "\-C";)
Anders B
9
@StvnW ... Nie wiem, czy nazwać tę meta (w bardziej ogólnym kontekście niż w kontekście SO), czy jak ją nazwać. Odpowiedziałeś na pytanie, pokazując, jak użyć odpowiedzi, aby znaleźć odpowiedź.
bballdave025,

Odpowiedzi:

4531

W przypadku BSD lub GNU grep można użyć, -B numaby ustawić liczbę linii przed dopasowaniem i -A numliczbę linii po dopasowaniu.

grep -B 3 -A 2 foo README.txt

Jeśli chcesz mieć taką samą liczbę linii przed i po, możesz użyć -C num.

grep -C 3 foo README.txt

To pokaże 3 linie przed i 3 linie po.

Pat Notz
źródło
56
Jest dobry, ale niestety grep Solaris tego nie obsługuje. Zobacz ten link do solaris: unix.com/solaris/33533-grep-display-few-lines-before-after.html
рüффп
9
Ok, ale co jeśli chcesz pokazać wszystkie wiersze wyników po meczu? grep -A0 i grep -A-1 nie odcinają ...
g33kz0r
2
z jakiegoś powodu nie działa dla mnie, chociaż wspomniano na moich stronach podręcznika.
Hayri Uğur Koltuk
2
Jeśli korzystasz z HP-UX env, żadna z wersji grep nie będzie działać tak jak w Solarisie. Był w stanie użyć linku Solaris, ale w tym linku zastąpił nawk awk.
zkarthik
6
-n jest dla numerów linii, ale dla niektórych wersji grep -n # pokaże # otaczające linie (jak -c) z numerami linii. To przydatny skrót, do którego wchodzę, gdy potrzebuję kontekstu.
Anthony DiSanti,
607

-Ai -Bbędzie działać, jak będzie -C n(dla nlinii kontekstu), lub po prostu -n(dla nlinii kontekstu ... o ile n wynosi od 1 do 9).

Stu
źródło
Wypróbowałem -nformat i okazało się, że działa tylko do 9. Na 15to zwraca 5 linii
Deepak Mahakale
7
@DeepakMahakale Jest to prawdopodobnie związane ze sposobem, w jaki argumenty / opcje wiersza polecenia są zazwyczaj analizowane przez programy POSIX. Opcja specifier jest pojedynczym znakiem (takich jak -A, -Blub -C). Zwykle po specyfikatorze opcji znajduje się wartość ( -o a.outokreślająca plik wyjściowy w GCC), ale może również działać jako zwykły przełącznik / flaga ( -gaby umożliwić debugowanie informacji w GCC). Jednak odstępy między opcjami są opcjonalne, więc w przypadku opcji bez wartości można je scalić ( -ABC), co oznacza, że -15jest interpretowany -1 -5(dwie oddzielne opcje) i -5zastępuje -1.
natiiix,
1
-5 jest szybszy niż oba -A 5 -B 5. Nie należy ich używać razem. Jest czytelniejszy dla innych czytelników skryptu, jeśli wybierzesz -A lub -B lub -C powyżej -9.
Eric Aldinger
76

ack działa z podobnymi argumentami jak grep i akceptuje -C. Ale zwykle lepiej jest przeszukiwać kod.

Elmarco
źródło
5
ack obsługuje również -A -B.
Shuo
Ack jest lepszy niż grep na wiele sposobów. Jest szybszy dzięki prostszej składni.
chim
1
Zaletą grep jest to, że jest instalowane domyślnie w wielu systemach.
Marc Z
1
@MarcZ: To prawda, że ​​grep jest częściej instalowany domyślnie niż ack, ale ack jest przenośnym, samodzielnym skryptem. Nie trzeba go kompilować ani instalować w katalogu systemowym, takim jak / usr / bin /. Po pobraniu i umieszczeniu w katalogu wymienionym w $ PATH (i ustawionym bicie uprawnień eXecute), powinien on działać od razu. (Żadne uprawnienia sudo ani roota nie są wymagane, aby dostać się do pracy.)
JL
To pytanie dotyczy grep, nie jest pewne użycie go do „reklamowania się” ack(co jest naprawdę świetnym narzędziem) - to dobry pomysł…
MonsieurDart
39
grep astring myfile -A 5 -B 5

Spowoduje to wstawienie „myfile” do „astring” i wyświetlenie 5 linii przed i po każdym meczu

dbr
źródło
19
„grep astring myfile -C 5” zrobi to samo
Syed Siraj Uddin
20

Zwykle używam

grep searchstring file -C n # n for number of lines of context up and down

Wiele narzędzi, takich jak grep, ma również naprawdę świetne pliki man. Znalazłem się powołując się na stronie man grep wiele, ponieważ jest tak wiele można zrobić z nim.

man grep

Wiele narzędzi GNU ma także stronę informacyjną, która może zawierać bardziej przydatne informacje oprócz strony man.

info grep
Sam Merrell
źródło
13

Użyj grep

$ grep --help | grep -i context
Context control:
  -B, --before-context=NUM  print NUM lines of leading context
  -A, --after-context=NUM   print NUM lines of trailing context
  -C, --context=NUM         print NUM lines of output context
  -NUM                      same as --context=NUM
Chiel ten Brinke
źródło
Nie przeczytałeś zaakceptowanej odpowiedzi? Powtarzasz tylko to, co już zostało powiedziane na pytanie, które ma prawie 10 lat ...
Yokai
7
Oh przepraszam Yokai. Ale nie czytam nic o grepowaniu w sekcji pomocy grep, aby uzyskać odpowiedź.
Chiel ten Brinke
1
@Yokai Oprócz tego, co powiedziała Chiel ten Brinke, w przyjętej odpowiedzi nie wspomniano o długich opcjach
użytkownik3738870,
10

Wyszukaj „17655” w „/some/file.txt”, pokazując kontekst 10 linii przed i po (używając Awk), dane wyjściowe poprzedzone numerem linii, a następnie dwukropkiem. Użyj tego w systemie Solaris, gdy „grep” nie obsługuje opcji „- [ACB]”.

awk '

/17655/ {
        for (i = (b + 1) % 10; i != b; i = (i + 1) % 10) {
                print before[i]
        }
        print (NR ":" ($0))
        a = 10
}

a-- > 0 {
        print (NR ":" ($0))
}

{
        before[b] = (NR ":" ($0))
        b = (b + 1) % 10
}' /some/file.txt;
Malcolm Boekhoff
źródło
7

ripgrep

Jeśli zależy Ci na wydajności, użyj ripgreppodobnej składni grep, np

rg -C5 "pattern" .

-C, --context NUM- Pokaż NUM wierszy przed i po każdym meczu.

Istnieją również parametry takie jak -A/ --after-contexti -B/ --before-context.

Narzędzie zostało zbudowane na silniku regularnym Rust, co czyni go bardzo wydajnym w przypadku dużych danych.

kenorb
źródło
5

Oto rozwiązanie @Ygor wawk

awk 'c-->0;$0~s{if(b)for(c=b+1;c>1;c--)print r[(NR-c+1)%b];print;c=a}b{r[NR%b]=$0}' b=3 a=3 s="pattern" myfile

Uwaga: Zamień ai bzmienne z liczbą linii przed i po.

Jest to szczególnie przydatne dla systemu, który nie obsługuje grepa -A, -Bi -Cparametry.

kenorb
źródło
4
$ grep thestring thefile -5

-5wyświetla 5linie powyżej i poniżej dopasowania „ciąg znaków” jest równoważny z -C 5lub -A 5 -B 5.

JBone
źródło
4

Grep ma opcję o nazwie Context Line Control, możesz jej użyć --context, po prostu

| grep -C 5

lub

| grep -5

Powinien załatwić sprawę

główny
źródło
1

Robię to w zwarty sposób

grep -5 string file

To jest odpowiednik

grep -A 5 -B 5 string file
franzisk
źródło
0

Jeśli często wyszukujesz kod, AG srebrny wyszukiwarka jest znacznie wydajniejszy (tj. Szybszy) niż grep.

Wyświetlane są linie kontekstu za pomocą opcji -C.

Na przykład:

ag -C 3 "foo" myFile

line 1
line 2
line 3
line that has "foo"
line 5
line 6
line 7
Róża
źródło