使用awk提取日志文件中两个字符串之间的数字

时间:2016-09-06 10:04:56

标签: regex bash awk

这是日志行的示例: 我想找到callee_num:<<"文本块后面的数字,直到下一个&gt;&gt ;.

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

什么是正确的解决方案? (感谢)

5 个答案:

答案 0 :(得分:4)

您可以使用sed执行此操作,默认情况下使用-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

答案 1 :(得分:1)

使用PCRE {grep

-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

答案 2 :(得分:1)

又一个awk:

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

被叫号码在第7个字段中(即awk '{print $7}' file将输出):

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

如果在该字段中找到<<"$7 ~ /<<\"/),则截断该字段中的双引号: callee_num:<<" {{1} }的&#34;&GT;&GT;

答案 3 :(得分: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}}功能,如其他答案帖子所述。

答案 4 :(得分:0)

 awk '{split( $0,a,"callee_num:<<|>>") } {gsub(/"/,"",a[3]);print a[3]}' filename
 +6182290000648