2016-09-06 3 views
0

Это пример строки журнала: Я хочу найти номер, который появляется после callee_num:<<" блок текста и до следующего >>.Извлечь число между двумя строками в файле журнала с awk

2016-08-21T06:37:36.830627+00:00 cccc eservice[9999]: INFO con_pr: user:<<"conxa3">> callee_num:<<"+6182290000648">> sid:<<"xxxxxxxxx160821082523657">> credits:-2.5 result:ok provider:outqtm.ym.ms 
2016-08-21T06:37:42.728469+00:00 cccc eservice[32499]: INFO con_end_procr: user:conxa3 callee_num:+6182290000648 sid:xxxxxxxxx160821082523657 duration:725 result:ok provider:outqtm.ym.ms 

Освобожденные результат с помощью awk должно быть +6182290000648 только из первой строки.

Это то, что я пытался, но не работает:

awk -F 'callee_num:<<" |\"' '{print $2}' filename 

Что такое правильное решение? (Спасибо)

+0

эй, потому что в первой строке у меня есть 'callee_num: <<" ', который является моим шаблоном. @fedorqui –

+1

@ fedorqui thx для вашего комментария. Я изменил свой вопрос. –

ответ

4

Вы можете сделать это с помощью СЭД, используя -n отключить печать по умолчанию:

sed -n 's/.*callee_num:<<"\([+0-9]*\)">.*/\1/p' file 

Когда совпадает с рисунком, часть между двойными кавычками захватывается и используется в замене, отбрасывая остальной части линии.

Конечно, можно с AWK тоже:

awk 'sub(/.*callee_num:<<"/, "") && sub(/">.*/, "")' file 

Это печатает все строки, где две замены являются успешными. В отличие от версии, использующей sed, она не проверяет, является ли часть между кавычками числовой. Если вы хотите, вы можете добавить в дальнейшей проверке, как это:

awk 'sub(/.*callee_num:<<"/, "") && sub(/">.*/, "") && /^[+0-9]+$/' file 

Это гарантирует, что после того, как две замены сделаны, все, что вы остаетесь с собой смесь + и цифры от 0 до 9.

Проблема с вашей попыткой использования awk заключается в том, что ваш разделитель полей может быть ", что сделает второе поле conxa3.

+0

Только один вопрос в вашем sed, что такое '\ 1'? –

+0

'\ 1' - это обратная ссылка, которая относится к первой группе, захваченной в круглых скобках в шаблоне поиска. –

+0

Используя выражение в команде 'sed', вы также можете вызвать' awk' с 'match' и сказать:' awk 'match ($ 0,/callee_num: << \ "([0-9 +] *) \" >> /, res) {print res [1]} 'file'. – fedorqui

1

grep с PCRE (-P):

grep -Po 'callee_num:<<"\K\+\d+' file.txt 

С sed:

sed -nE 's/.* callee_num:<<"(\+[[:digit:]]+)".*/\1/p' file.txt 

С GNU awk:

awk 'match($0, /.* callee_num:<<\"(\+[0-9]+)\".*"/, a) {print a[1]}' file.txt 

Пример:

% cat file.txt 
2016-08-21T06:37:36.830627+00:00 cccc eservice[9999]: INFO con_pr: user:<<"conxa3">> callee_num:<<"+6182290000648">> sid:<<"xxxxxxxxx160821082523657">> credits:-2.5 result:ok provider:outqtm.ym.ms 
2016-08-21T06:37:42.728469+00:00 cccc eservice[32499]: INFO con_end_procr: user:conxa3 callee_num:+6182290000648 sid:xxxxxxxxx160821082523657 duration:725 result:ok provider:outqtm.ym.ms 

% grep -Po 'callee_num:<<"\K\+\d+' file.txt 
+6182290000648 

% sed -nE 's/.* callee_num:<<"(\+[[:digit:]]+)".*/\1/p' file.txt 
+6182290000648 

% awk 'match($0, /.* callee_num:<<\"(\+[0-9]+)\".*"/, a) {print a[1]}' file.txt  
+6182290000648 
+0

Мне нужен awk. thx –

+0

У вас означает, что с 'awk' это невозможно? @heemayl –

+0

@MaryamPashmi Проверьте мои правки. – heemayl

0

Давая 2 разделителя полей, разделенных |, вы указываете awk, чтобы использовать их как разделители.

Так что, когда awk ищет либо callee_num:<<" или " и так как он находит ", прежде чем conxa3 и снова после этой строки. Следовательно, ваш выход будет conxa3.Короче говоря, ваша команда awk аналогична:

$ awk -F '"' '{print $2}' /tmp/t 
conxa3 

Если вы уверены, что ваша строка будет то же самое, вы можете вместо печати $4:

$ awk -F '"' '{print $4}' /tmp/t 
+6182290000648 

Или вы можете использовать sub функцию awk, как описано другими сообщениями ответа.

1

Еще один AWK:

$ awk '$7 ~ /<<\"/ {gsub(/.*<<"|">>$/, "", $7); print $7}' file 
+6182290000648 

Число вызываемая в 7-ом поле (т. Е awk '{print $7}' file бы выход):

callee_num:<<"+6182290000648">> 
callee_num:+6182290000648 

Если <<" находится в этой области ($7 ~ /<<\"/), урезать до и из двойных котировок в этом поле: callee_num:<<"+6182290000648 ">>

+0

Не понимаю, почему вы использовали 'gsub'? –

+0

'sub'stops после первого совпадения' gsub' не делает. Вы должны усекать с самого начала и до конца. В этом 'gsub()' есть два совпадения, разделенных '' '(логическим ИЛИ). –

0
awk '{split($0,a,"callee_num:<<|>>") } {gsub(/"/,"",a[3]);print a[3]}' filename 
+6182290000648 
Смежные вопросы