LINUX.ORG.RU

sed: выводит только последние вхождение

 


0

2

Есть длинная строка

[..."serialNumber":"1","subject":"service.site.com","issuer":"CA","validFrom":1455235200000,"validTo":1,"numLogs":3,"hash":"a","firstDnsName":"service.site.com","numDnsNames":1},{"serialNumber":"4","subject":"vc.site.com","issuer":"abc","validFrom":4,"validTo":3,"numLogs":3,"hash":"a","firstDnsName":"vc.site.com","numDnsNames":1}...]

нужно из нее выбрать значения subject т.е. получить на выходе

service.site.com

vc.site.com

Столкнулся с двумя проблемами:

1.

sed 's/^.*subject":"\(.*\)".*$/\1/' ./1.txt

Выбираем только то что после subject между "", и вроде бы логично и должно корректно работать, но не работает.

2. Даже с этой кривой регуляркой sed выбирает только последние вхождение в этой строке, а не все.

Врачи, подскажите как лечить.


Первую проблему решил так:

sed 's/^.*subject":"\(.*\)","issuer.*$/\1/' ./1.txt

но если честно то не понял почему так происходит.

hama
() автор топика

sed обязательно?

$ echo '[..."serialNumber":"1","subject":"service.site.com","issuer":"CA","validFrom":1455235200000,"validTo":1,"numLogs":3,"hash":"a","firstDnsName":"service.site.com","numDnsNames":1},{"serialNumber":"4","subject":"vc.site.com","issuer":"abc","validFrom":4,"validTo":3,"numLogs":3,"hash":"a","firstDnsName":"vc.site.com","numDnsNames":1}...]' | awk -F=":" -v RS="," '$1~/"subject"/ {print}' | sed 's/\"//g; s/subject://g'
service.site.com
vc.site.com

Но вообще если тебе json парсить так возьми нормальный инструмент.

Что касается того, почему выбирается вся строка в первом случае - это называется «жадные» выражения или как-то так - в общем когда ты говоришь «выбирать текст до кавычки» он (sed) захавает столько текста, сколько сможет пока не наткнется на последнюю возможную кавычку. То же самое и с тем почему выбирается только последний вариант - пропущено будет столько ".*"-символов, сколько будет возможно пока не придем к последней возможной выборке. Не знаю как это объяснить нормальным языком и скорее всего что-то напутал (никогда не занимался таким парсингом на sed), но примерно суть такая.

alozovskoy ★★★★★
()
Последнее исправление: alozovskoy (всего исправлений: 1)
Ответ на: комментарий от alozovskoy

Нет, просто мне хотелось за один раз решить задачу при помощи sed, а не использовать комплект из grep, awk и т.п.

hama
() автор топика

а. наверное, нужно поменять \(.*\) на \([^«]*\), т.к. иначе оно жадно считывает до последней кавычки

б. после последнего / добавить g (as in s/from/to/g). g - от global

anonymous
()
Ответ на: комментарий от anonymous

в предыдущем сообщении в а. вместо кавычки ёлочкой должна быть двойная кавычка.

anonymous
()
Ответ на: комментарий от anonymous

б. Это первое что пробовал, не помогает.

hama
() автор топика
Ответ на: комментарий от hama

Выбирает все символы кроме кавычки. Ты используешь .* - это значит «любое количество любых символов», а конструкция из предложенного аноном примера - «выбирать все символы, кроме кавычек» (вот как раз ^ и означает «кроме»).

alozovskoy ★★★★★
()
Ответ на: комментарий от anonymous

пардон, надо так: cat ./1.txt | tr '{},' '\012' | grep subject | awk -F '«' '{print $4;}' -

anonymous
()
$ sed 's@"subject":"\([^"]*\)"@\n\1\n@g' 1.txt | sed -n 'n;p'
salsa
()
$ echo '[..."serialNumber":"1","subject":"service.site.com","issuer":"CA","validFrom":1455235200000,"validTo":1,"numLogs":3,"hash":"a","firstDnsName":"service.site.com","numDnsNames":1},{"serialNumber":"4","subject":"vc.site.com","issuer":"abc","validFrom":4,"validTo":3,"numLogs":3,"hash":"a","firstDnsName":"vc.site.com","numDnsNames":1}...]' | sed 's/"subject":"/\n"subject":"/g;' | sed -n 's/"subject":"//p;'| sed 's/".*//'
service.site.com
vc.site.com

Как-то так:

  1. sed — разрезать по строкам;
  2. sed — отфильтровать нужные и отрезать левую часть;
  3. sed — отрезать правую часть.
justAmoment ★★★★★
()

А нужно ли бояться перла?

echo '{"num": "number", "txt": "text"}'  | perl -MLWP::Simple -MJSON -ne '$json = decode_json($_); print($json->{txt} . "\n");'
text
anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.