2011-11-12 14 views
83

Korzystanie z tego:Grep postacie przed i po meczu?

grep -A1 -B1 "test_pattern" file 

będzie produkować jedną linię przed i po dopasowanego wzorca w pliku. Czy istnieje sposób wyświetlania nie linii, ale określoną liczbę znaków?

Linie w moim pliku są dość duże, więc nie jestem zainteresowany drukowaniem całej linii, ale raczej obserwuję tylko dopasowanie w kontekście. Wszelkie sugestie, jak to zrobić?

Odpowiedz

103

3 znaków przed i 4 znaki po

$> echo "some123_string_and_another" | grep -o -P '.{0,3}string.{0,4}' 
23_string_and 
+4

Dobra odpowiedź dla małych ilości danych, ale zaczyna się robić powoli, gdy pasujesz do> 100 znaków - np. w moim gigantycznym pliku xml chcę {1.200} przed i po, i jest on zbyt wolny w użyciu. – Benubird

+3

Wersja awk autorstwa @amit_g jest znacznie szybsza. – ssobczak

+1

Niedostępne w systemie Mac OSX, więc tak naprawdę nie jest to rozwiązanie powszechnie dostępne. Wersja -E (wymieniona poniżej) jest lepszym rozwiązaniem. Co to jest -P? Czytaj dalej ... -P, --perl-regexp Interpretacja PATTERN jako wyrażenia regularnego Perla (PCRE, patrz poniżej). Jest to wysoce eksperymentalne i grep -P może ostrzegać o niezatwierdzonych funkcjach. – Xofo

23

Można użyć

awk '/test_pattern/ { 
    match($0, /test_pattern/); print substr($0, RSTART - 10, RLENGTH + 20); 
}' file 
+2

Działa ładnie nawet z nieco większymi plikami również – Touko

+3

jak można tego użyć, aby znaleźć wiele dopasowań na linię? – koox00

+0

Czy ktoś może zaktualizować to dla wielu dopasowań? – Pranab

11

Masz na myśli coś takiego:

grep -o '.\{0,20\}test_pattern.\{0,20\}' file 

?

To będzie wydrukować do dwudziestu znaków po każdej stronie test_pattern. Notacja \{0,20\} jest podobna do *, ale określa od zera do dwudziestu powtórzeń zamiast zera lub więcej. -o mówi, że pokazuje tylko sam mecz, a nie całą linię.

+0

To polecenie nie działa dla mnie: 'grep: Niepoprawna zawartość \ {\}' –

+0

Ten działał w terminalu OSX. – hapi

70
grep -E -o ".{0,5}test_pattern.{0,5}" test.txt 

Spowoduje to dopasowanie do 5 znaków przed i po schemacie. Przełącznik -o mówi grep, aby pokazywał tylko dopasowanie, a -E używał rozszerzonego wyrażenia regularnego. Upewnij się, że umieścisz cytaty wokół swojego wyrażenia, w przeciwnym razie może zostać zinterpretowane przez powłokę.

0

Z gawk, można użyć dopasowania funkcji:

x="hey there how are you" 
    echo "$x" |awk --re-interval '{match($0,/(.{4})how(.{4})/,a);print a[1],a[2]}' 
    ere are 

Jeśli jesteś ok z perl, bardziej elastyczne rozwiązanie: Po wydrukuje trzy znaki przed wzór następnie faktycznego wzoru, a następnie 5 znaków na wzór .

echo hey there how are you |perl -lne 'print "$1$2$3" if /(.{3})(there)(.{5})/' 
ey there how 

Można to również zastosować do słów, a nie tylko znaków. Po wpisaniu zostanie wydrukowane jedno słowo przed właściwym pasującym ciągiem.

echo hey there how are you |perl -lne 'print $1 if /(\w+) there/' 
hey 

Po drukuje jedno słowo po wzoru:

echo hey there how are you |perl -lne 'print $2 if /(\w+) there (\w+)/' 
how 

Po drukuje jedno słowo przed wzorca, wówczas rzeczywista Word, a następnie jednym słowem po wzoru:

echo hey there how are you |perl -lne 'print "$1$2$3" if /(\w+)(there)(\w+)/' 
hey there how