以下是我的TCL脚本:
set line {
Jul 24 21:06:40 2014: %AUTH-6-INFO: login[1765]: user 'admin' on 'pts/1' logged
Jul 24 21:05:15 2014: %DATAPLANE-5-: Unrecognized HTTP URL www.58.net. Flow: 0x2
Jul 24 21:04:39 2014: %DATAPLANE-5-: Unrecognized HTTP URL static.58.com. Flow:
Jul 24 21:04:38 2014: %DATAPLANE-5-: Unrecognized HTTP URL www.google-analytics.
com. Flow: 0x2265394048.
Jul 24 21:04:36 2014: %DATAPLANE-5-: Unrecognized HTTP URL track.58.co.in. Flow: 0
}
if {[regexp -all {Unrecognized HTTP URL ([a-z0-9.]*) Flow} $line junk one]} {
puts $one
}使用上面的TCL脚本,我希望grep "$line“变量中的URL名称。现在可以只显示在末尾的URL名称(track.58.co.in.)。如何使用TCL正则表达式对所有URL名称进行grep。
此外,我还想将这些grepped导出到Microsoft file.How以完成此操作?请帮我提一下你的想法。
谢谢,
Balu P.
发布于 2014-07-24 17:59:52
(我以前的回答有点杂乱无章,为了改变而稍微改变一下,这个比较好。请注意,我的答案现在与glenn jackman的回答非常相似。不过,还有一些细微的差别。自从答案被接受以来,我一直把它放在课文的末尾。)
而不是
if {[regexp -all {Unrecognized HTTP URL ([a-z0-9.]*) Flow} $line junk one]} {
puts $one
}使用
set urls {}
foreach {junk url} [regexp -all -inline {Unrecognized HTTP URL ([a-z0-9.]*) Flow} $line] {
lappend urls [string trim $url .]
}或(Tcl 8.6+)
set urls [lmap {junk url} [regexp -all -inline {Unrecognized HTTP URL ([a-z0-9.]*) Flow} $line] {string trim $url .}]使用regexp和变量名调用-all,将最后一组匹配存储在这些变量中,并返回true或false,指示是否匹配。相反,使用-inline调用返回一个列表,该列表是所有匹配集的连接(如果该列表为空,则没有匹配)。通过使用foreach或lmap遍历返回的列表并选择想要的项目,您可以收集urls列表。
日志在您可能不想要的每个url之后添加一个点,并且string trim $url .修复了这个问题(如果它们出现的话,它也会删除前面的点)。使用正则表达式{Unrecognized HTTP URL ([a-z0-9.]*)\. Flow}或{Unrecognized HTTP URL (.*?)\. Flow}是解决此问题的另一种方法,方法是将该点排除在捕获之外。
请注意,您使用的正则表达式并不匹配所有有效的urls,它也匹配一些无效的urls(这在这里不是一个大问题,因为您正在提取实际的日志urls)。具体来说,因为"com“之前的行中断,它错过了第三个url。如果这是一个问题,那么故意过高urls可能是有意义的:
regexp -all -inline {Unrecognized HTTP URL (.*?) Flow} $line它使用一个非贪婪的匹配来获取"URL“和"Flow”之间的任何内容(包括嵌入式空格)。在接下来的步骤中,您可以通过一个筛选器传递url列表,该过滤器丢弃或标记对您来说无效的任何url。
将URL导出到Excel的最简单方法应该是将它们写入文本文件:
package require fileutil
::fileutil::writeFile urllist.txt [join $urls \n]\n或(再次假设Tcl 8.6)
try {
open urllist.txt w
} on ok f {
chan puts $f [join $urls \n]
} finally {
catch {chan close $f}
}然后在Excel中打开文件;每个URL将位于自己行的第一列中。
文档:捕捉、成龙、如果、加入、拉皮、lmap、打开、套餐、雷杰普、设置、字符串、试一试
旧答案
您可以使用以下命令获取所有URL:
lmap item [regexp -all -inline {URL\s+\S+} $line] {
string trimright [lindex $item 1] .
}如果使用-all和match变量(在您的示例中是junk和one),则只得到最后一个匹配。相反,请同时使用-all和-inline,这将给出匹配的列表。您实际上只需要匹配序列"URL",一个或多个空格字符(\s+),然后是一个非空间字符(\S+)序列。这给了你名单
{{URL www.58.net} {URL static.58.com} {URL www.google-analytics} {URL track.58.co.in}}如果$line的任何部分与正则表达式没有匹配,则列表将为空。
如果要打印所有URL,可以编写:
set urls [lmap item [regexp -all -inline {URL\s+\S+} $line] {
string trimright [lindex $item 1] .
}]
foreach url $urls {
puts $url
}如果您有TCL8.6,可以使用lmap命令将该列表映射到另一个列表,该列表由第一个列表中每个元素的第二个元素组成。
如果您有较早版本的Tcl,请执行以下操作:
set urls [list]
foreach item [regexp -all -inline {URL\s+\S+} $line] {
lappend urls [string trimright [lindex $item 1] .]
}
foreach url $urls {
puts $url
}现在,您可以使用正则表达式中\S+周围的捕获来获得一个列表,其中每个其他元素(元素#1、#3等)都是URL,但这实际上使获取URL列表变得有点困难(glenn在他的回答中采用了这条路线)。
请注意,第三个URL已损坏,因为其中有空白。这是在粘贴示例时发生的,还是在实际数据中会出现这样的散乱空间字符?
(关于如何导出到Excel的说明移到新答案。)
文档:捕捉、成龙、前程、拉皮、lindex、lmap、打开、看跌期权、雷杰普、设置、字符串、试一试
(注意:评论中提到的'Hoodiecrow‘是我,我之前用过这个尼克。)
发布于 2014-07-24 18:13:16
% regexp -inline -all {HTTP URL (\S+)\.} $line
{HTTP URL www.58.net.} www.58.net {HTTP URL static.58.com.} static.58.com {HTTP URL www.google-analytics.} www.google-analytics {HTTP URL track.58.co.in.} track.58.co.in
% foreach {match submatch} [regexp -inline -all {HTTP URL (\S+)\.} $line] {
lappend urls $submatch
}
% set urls
www.58.net static.58.com www.google-analytics track.58.co.inhttps://stackoverflow.com/questions/24940569
复制相似问题