以下是我的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名称。现在,仅可以grep出现在末尾的URL名称(track.58.co.in。)。如何使用TCL正则表达式grep所有URL名称。
我也想将这些grepped URL名称导出到Microsoft Excel文件中。如何执行此操作?请帮我提出您的想法。
谢谢,
Balu P.
(我以前的答案有点杂乱无章,这是一个比较好的方法。请注意,我的答案现在与格伦·杰克曼的答案非常相似。不过,仍然存在一些细微的差异。答案已被接受,我将其保留在本文的末尾。)
代替
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
而是调用with返回一个列表,该列表是所有匹配项集合的串联(如果此列表为空,则没有匹配项)。在这种情况下,通过使用foreach
或遍历返回的列表,lmap
然后选择所需的项目,您可以收集网址列表。
日志会在您可能不需要的每个URL之后添加一个点,并提供相应的string trim $url .
解决方案(如果出现,它还会删除前导点)。通过从捕获中排除该点,使用正则表达式{Unrecognized HTTP URL ([a-z0-9.]*)\. Flow}
或是{Unrecognized HTTP URL (.*?)\. Flow}
解决该问题的另一种方法。
请注意,您使用的正则表达式并不匹配所有有效的url,并且确实匹配了几个无效的url(在这里这不是一个大问题,因为您正在提取实际记录的url)。具体来说,由于“ com”之前的换行符,它错过了第三个URL。如果这是一个问题,则故意将网址过度匹配可能是有道理的:
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中打开文件;每个网址将在其自己行的第一列中。
文档:catch,chan,if,join,lappend,lmap,open,package,regexp,set,string,try
您可以使用以下命令获取所有URL:
lmap item [regexp -all -inline {URL\s+\S+} $line] {
string trimright [lindex $item 1] .
}
如果您使用-all
并匹配变量(在你的情况,junk
和one
),你只得到了最后一场比赛。而是将-all
和-inline
一起使用,从而为您提供匹配项列表。您实际上只需要匹配sequence "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
}
如果您具有Tcl 8.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 jackman在回答中采用了该路线)。
请注意,第三个URL已损坏,因为其中有空白。粘贴示例时会发生这种情况吗,还是在真实数据中会出现这种杂乱的空格字符?
(有关如何导出到Excel的说明已移至新答案。)
文档:catch,chan,foreach,lappend,lindex,lmap,open,puts,regexp,set,string,try
(注意:评论中提到的“ Hoodecrow”是我,我之前使用了这个昵称。)
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句