[英]How to grep a word first then how to grep the output according to that word using TCL regexp?
This is my TCL Script: 这是我的TCL脚本:
set test {
device#more system:/proc/dataplane/fw/application
1 : Amazon Instant Video (num of policy actions: 0)
port-proto:
http urls :
*(www.amazon.com/Instant-Video)*
dns names :
https client-hello servNames :
https server-hello servNames :
https server-certificate commonNames :
Application stats :
Bytes Uploaded : 0
Bytes Download : 0
Num Flows : 0
2 : SIP (num of policy actions: 0)
port-proto:
Proto 6-6, sport 0-65535, dport 5060-5061
Proto 17-17, sport 0-65535, dport 5060-5061
http urls :
dns names :
https client-hello servNames :
https server-hello servNames :
https server-certificate commonNames :
Application stats :
Bytes Uploaded : 0
Bytes Download : 0
Num Flows : 0
3 : Photobucket (num of policy actions: 0)
port-proto:
http urls :
*(www.pbsrc.com)*
*(www.photobucket.com)*
dns names :
*.photobucket.co (2)
*.photobucket.com (2)
https client-hello servNames :
https server-hello servNames :
https server-certificate commonNames :
Application stats :
Bytes Uploaded : 34
Bytes Download : 44
Num Flows : 78
4 : Filestub (num of policy actions: 0)
port-proto:
http urls :
*(www.filestub.com)*
dns names :
*.filestub.com (2)
https client-hello servNames :
https server-hello servNames :
https server-certificate commonNames :
Application stats :
Bytes Uploaded : 0
Bytes Download : 0
Num Flows : 0
--More--
device#
}
set lines [split $test \n] ; # split using new line char(\n)
set data [join $lines :]
if { [regexp {Photobucket.*(Bytes Uploaded : .* Bytes Download:)} $data x y]} {
set y [string trimright $y {: }]
puts "Bytes uploaded : $y"
}
I am trying to find the Bytes downloaded and uploaded to the application called "Photobucket" in $test variable. 我试图在$ test变量中找到下载并上传到名为“ Photobucket”的应用程序的字节。
STEPS that script to do:
1. First identify the word "Photobucket"
2. Then grep for "Bytes Uploaded : <any number> and Bytes Download : <any number>, Num Flows : <any number> for that application "Photobucket".
Output should be:
Application Name : "Photobucket"
Bytes Uploaded : 34
Bytes Download : 44
Num Flows : 78
When I run my script I am getting only the last line in $test. 运行脚本时,我只得到$ test中的最后一行。
Please help me to fix this. 请帮助我解决此问题。
Thanks, 谢谢,
Kumar 库玛
First, I think that you didn't put the regex that you are using in your question because your regex doesn't match at all because of a missing space. 首先,我认为您没有将正在使用的正则表达式放在问题中,因为由于缺少空格,您的正则表达式根本不匹配。 It should be:
它应该是:
Photobucket.*(Bytes Uploaded : .* Bytes Download :)
Now, the problem with this regex is that .*
is greedy and will match till the end of the string (since it matches anything and everything), and then backtrack one character at a time until the whole regex is matched (that is where the last Bytes Uploaded :
and Bytes Download :
is matched), or if no match is found, then the regex fails to match. 现在,此正则表达式的问题是
.*
是贪婪的,它将一直匹配到字符串的末尾(因为它匹配所有内容),然后一次回溯一个字符,直到匹配整个正则表达式(即最后Bytes Uploaded :
与Bytes Download :
数相匹配),或者如果找不到匹配项,则正则表达式将无法匹配。 What you need is to make is the .*
lazy (or match as little as possible) with the ?
您需要使
.*
变得懒惰(或尽可能少地匹配) ?
modifier: 修饰符:
Photobucket.*?(Bytes Uploaded : .*? Bytes Download :)
The above will match the correct part, except you will have an incorrect value in y
since you will also have Bytes Uploaded
and such. 上面的将匹配正确的部分,除了您在
y
值不正确之外,因为您还将具有Bytes Uploaded
等等。 The trim cannot remove those. 装饰无法将其移除。 You might thus change the regex a bit more:
因此,您可以对正则表达式进行更多更改:
Photobucket.*?Bytes Uploaded : (\S+):
This will put non space characters, matched by (\\S+)
into the variable y
. 这会将与
(\\S+)
匹配的非空格字符放入变量y
。 You don't need to trim after that. 之后,您无需修剪。
And you don't need to split and rejoin if you change the regex: 而且,如果您更改正则表达式,则无需拆分并重新加入:
if { [regexp {Photobucket.*?Bytes Uploaded : (\S+)\s} $test - y]} {
puts "Bytes uploaded : $y"
}
To get all the three values, you then just need to add them at the end: 要获取所有三个值,只需在最后添加它们:
if { [regexp {Photobucket.*?Bytes Uploaded : (\S+)\s+Bytes Download : (\S+)\s+Num Flows : (\S+)\s+} $test - x y z]} {
puts "Bytes uploaded : $x"
puts "Byte download : $y"
puts "Num flows : $z"
}
You can use string commands instead of a giant regex 您可以使用字符串命令代替巨大的正则表达式
set stats {"Bytes Uploaded" "Bytes Download" "Num Flows"}
set photobucket_idx [string first Photobucket $test]
foreach stat $stats {
set digits_start [expr {[string first "$stat : " $test $photobucket_idx] + [string length "$stat : "]}]
set digits_end [expr {[string first \n $test $digits_start] - 1}]
set digits($stat) [string range $test $digits_start $digits_end]
}
parray digits
outputs 输出
digits(Bytes Download) = 44
digits(Bytes Uploaded) = 34
digits(Num Flows) = 78
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.