2011-12-22 6 views
36

я следующую строку:Grep: группа захвата

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

и мне нужно получить значение «схемы версии», которая 1234 в этом примере.

Я попытался

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

однако он возвращает

"scheme_version":1234 

Как я могу это сделать? Я знаю, что могу добавить вызов sed, но я бы предпочел сделать это с помощью одного grep.

+0

Я не думаю, что это возможно только с «grep». Пару лет назад я много делал с манипуляциями с строками, часто прокладывая grep на такие вещи, как «sed» или «cut». Я предлагаю вам изучить «трубопровод» и команду «вырезать». –

+0

Я не очень часто использую grep, но, возможно, вы можете использовать выражение внешнего вида, как указано в принятом ответе в http://stackoverflow.com/questions/1247812/im-stuck-in-trying-to- Grep-нибудь-точно после имени. –

+1

Использовать [jq] (https://stedolan.github.io/jq) –

ответ

37

Это может работать для вас:

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

К сожалению, это не grep, так что пренебречь этим решением, если хотите.

Или придерживаться Grep и добавить:

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

Кажется, это лучший вариант для меня. – lstipakov

52

Вы должны будете использовать заглянуть за утверждение так, что он не включен в матче:

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

+0

Хмм, я получил grep: поддержка опции -P не скомпилирована в это двоичное значение --disable-perl-regexp – lstipakov

+4

@Stipa Без поддержки PCRE вы не может делать то, что вы хотите, с помощью grep, поскольку он не поддерживает обратные ссылки, т.е. '\ 1' – SiegeX

+1

+1' -P' perl отлично! – kev

30

Я бы рекомендовал использовать jq для работы. jq - это процессор JSON с командной строкой.

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

$ cat tmp | jq .scheme_version 
1234 
+1

Как я функционировал в жизни, не зная о jq. Вау. Благодаря! – brian

-1

Вы можете сделать это:

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

Хотя этот кодовый блок может ответить на вопрос OP, этот ответ был бы намного более полезен, если вы объясните, как этот код отличается от кода в вопросе, что вы изменили, почему вы его изменили и почему это решает проблема без введения других. – davejal

14

В качестве альтернативы к положительному методу назад ', предложенной SiegeX, вы можете сбросить начальную точку матча непосредственно после scheme_version": с последовательностью \K побега. Например,

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

Это перезапускает процесс согласования после того, как соответствие scheme_version":, и как правило, имеют значительно более высокую производительность по сравнению с положительным просмотром назад. Сравнение двух в regexp101 демонстрирует, что метод начала совпадения с возвратом занимает 37 шагов и 1 мс, тогда как метод положительного lookbehind занимает 194 шага и 21 мс.

Вы можете сравнить производительность самостоятельно на regex101, и вы можете подробнее узнать о сбросе начальной точки матча в PCRE documentation.

+0

Это _exactly_, что мне нужно; благодаря! – mklbtz

Смежные вопросы