grep otaczające znaki dopasowania

8

Szukam znaleźć i zastąpić w gigantycznym zrzucie bazy danych i nie robi tego, co moim zdaniem powinno się zdarzyć. Chciałbym grep dla mojego ciągu docelowego w pliku, a następnie zobaczyć około 8 znaków otaczających (w zależności od tego może być konieczne dostosowanie tej liczby). Jak mogę to zrobić?

Powodem, dla którego nie mogę tego zrobić, jest to, że istnieje wiele setek, jeśli nie tysiące dopasowań. Chcę uzyskać pewną liczbę znaków otaczających ciąg, a następnie potokować go uniqlub coś, aby zobaczyć, dlaczego moje wyszukiwanie i zamiana mają nieoczekiwane zachowania.

Ponadto w tej samej linii może znajdować się wiele dopasowań!

użytkownik394
źródło
To nie jest plik tekstowy?
enzotib
Tak jest, ale nawet same mecze są zbyt duże, by można je było zobaczyć.
użytkownik394,

Odpowiedzi:

12

Prosty sposób użycia grepbyłby podobny

grep -o "....yourtext...." /path/to/the/dump.sql

Liczba kropek odpowiada liczbie znaków przed / po grepowanym tekście. Ta -oopcja powoduje, że grepdane wyjściowe są tylko zgodne, a nie całe wiersze.

Aby użyć uniqna wyjściu, pamiętaj, że najpierw musisz posortować dane wyjściowe. Tak zazwyczaj byś zrobił

grep . . . | sort | uniq

Jeśli interesuje Cię liczba trafień dla każdego meczu, możesz uzyskać dobre wyniki za pomocą

grep . . . | sort | uniq -c | sort -n
rozcietrzewiacz
źródło
Surowy? Całkowicie wyrafinowane!
użytkownik394,
1
Można rozszerzyć na tym trochę za pomocą operatora powtarzania: grep -o '.\{8\}yourtext.\{8\}'. Jest to nieco mniej zawrotne niż liczenie 8 kropek.
Caleb
:) Przez prymitywne rozumiem, że nie bawisz się takimi rzeczami, jak liczenie dopasowanych znaków (używanie zakresów) lub zawężanie zestawów znaków.
rozcietrzewiacz
@Caleb i użytkownik394: Właśnie tego nie chciałem sugerować (i dlatego nazwałem moją metodę „surową”). Poza tym nie trzeba zapamiętywać konstrukcji operatora powtarzania - nawet szybciej jest pisać „.....” niż „. \ {6 \}”.
rozcietrzewiacz
7

Począwszy od odpowiedzi @rozcietrzewiacz, mogę rozwinąć do

pattern="string"
num=8
grep -on ".\{0,$num\}$pattern.\{0,$num\}" input-file
enzotib
źródło
1
„Surowa” sekwencja kropek cały czas wygląda coraz lepiej :)
Caleb
1
@Caleb: ogólnie rzecz biorąc, „prymitywna” odpowiedź to dobry początek, ale czasem ktoś chce się trochę rozwinąć.
enzotib,
1
Metoda sekwencji kropek nie znajdzie wzorców docelowych wyrównanych do lewej lub prawej; ta metoda będzie. (+1)
Peter.O,
2
PS .. Właśnie zauważyłem, że nie złapie wielu wystąpień wzoru w tym samym wierszu (jak wspomniano PO), gdy zakres końcowego „exta” pierwszego wzoru nakłada się na zakres wiodącego „dodatkowego” tekstu następnego wzoru
Peter.O,
@fred: tak, -odaje tylko pierwszy mecz, gdy dwa mecze pokrywają się:echo 'aaabbbccc' | grep -o 'bb
enzotib