2011-12-22 12 views
36

Mam następujący ciąg:grep: grupa przechwytywanie

{"_id":"scheme_version","_rev":"4-cad1842a7646b4497066e09c3788e724","scheme_version":1234} 

i trzeba uzyskać wartość „wersja programu”, który jest 1234 w tym przykładzie.

Próbowałem

grep -Eo "\"scheme_version\":(\w*)" 

jednak powraca on

"scheme_version":1234 

Jak mogę to zrobić? Wiem, że mogę dodać sed połączenia, ale wolałbym to zrobić z pojedynczym grep.

+0

Nie sądzę, że jest to możliwe tylko przy użyciu "grep". Kilka lat temu zrobiłem wiele z manipulacją strunami, często wyskakując do rzeczy takich jak "sed" lub "cut". Sugerowałbym, żebyś przestudiował "piping" i polecenie "cut". –

+0

Nie używam grep bardzo często, ale być może użyjesz wyrażenia typu look-behind, jak opisano w zaakceptowanej odpowiedzi na http://stackoverflow.com/questions/1247812/im-stuck-in-trying-to- grep-anything-just-after-name. –

+1

Użyj [jq] (https://stedolan.github.io/jq) –

Odpowiedz

37

ten może pracować dla Ciebie:

echo '{"_id":"scheme_version","_rev":"4-cad1842a7646b4497066e09c3788e724","scheme_version":1234}' | 
sed -n 's/.*"scheme_version":\([^}]*\)}/\1/p' 
1234 

Niestety to nie jest grep, więc zignoruj ​​to rozwiązanie, jeśli chcesz.

Albo trzymać z grep i dodać:

grep -Eo "\"scheme_version\":(\w*)"| cut -d: -f2 
+0

Wygląda na to, że jest to najlepsza dostępna opcja dla mnie. – lstipakov

52

Musisz użyć do obejrzenia za twierdzenie, że tak nie jest wliczone w meczu:

grep -Po '(?<=scheme_version":)[0-9]+'

+0

Hmm Mam grep: Obsługa opcji -P nie jest wkompilowana w ten plik binarny -disable-perl-regexp – lstipakov

+4

@Stipa Bez wsparcia PCRE nie może zrobić tego, co chcesz z grep, ponieważ nie obsługuje zwrotów wstecz, np. '\ 1' – SiegeX

+1

+1' -P' perl świetnie! – kev

30

Polecam skorzystanie jq do pracy. jq to procesor JSON z wiersza poleceń.

$ cat tmp 
{"_id":"scheme_version","_rev":"4-cad1842a7646b4497066e09c3788e724","scheme_version":1234} 

$ cat tmp | jq .scheme_version 
1234 
+1

Jak działałam w życiu, nie wiedząc o jq. Łał. Dzięki! – brian

-1

Można to zrobić:

$ echo '{"_id":"scheme_version","_rev":"4-cad1842a7646b4497066e09c3788e724","scheme_version":1234}' | awk -F ':' '{print $4}' | tr -d '}' 
+1

Podczas gdy ten blok kodu może odpowiedzieć na pytanie OP, ta odpowiedź byłaby o wiele bardziej użyteczna, gdybyś wyjaśnił, w jaki sposób ten kod różni się od kodu w pytaniu, co zmieniłeś, dlaczego go zmieniłeś i dlaczego rozwiązuje problem bez wprowadzania innych. – davejal

14

Jako alternatywę dla pozytywnego sposobu lookbehind sugerowanej przez SiegeX można zresetować punkt wyjścia do spotkania bezpośrednio po scheme_version": z sekwencji ucieczki \K. Np

$ grep -Po 'scheme_version":\K[0-9]+' 

to restartuje proces dopasowania produktów po dopasowane scheme_version": i ma tendencję do znacznie lepszą wydajność niż pozytywnego lookbehind. Porównanie dwóch na regexp101 pokazuje, że metoda początku dopasowania resetowania zajmuje 37 kroków i 1ms, podczas gdy pozytywna metoda lookbehind trwa 194 kroki i 21 ms.

Możesz porównać wydajność samodzielnie pod numerem regex101 i możesz przeczytać więcej o resetowaniu punktu początkowego meczu w PCRE documentation.

+0

To _exactly_ to, czego potrzebowałem; dzięki! – mklbtz