我有多个日志文件,其中包含带有标题的值:
我想创建一个头文件,其中包含第1列中的每一行作为单独的列标题,并且每行包含min - max并以列格式显示。
Info in log files:
Trace Header Min Max Mean
aaa 1 6 xx
bbb 2 7 xxx
我想要的是什么:
aaa bbb
1-6 2-7
感谢您的帮助
答案 0 :(得分:2)
试试这个(长列表应该在data
变量中,从文件中读取或其他):
foreach line [split $data \n] {
if {[scan $line {%s %d %d} header min max] eq 3} {
set result($header) $min-$max
}
}
% parray result
result(aaa) = 1-6
result(bbb) = 2-7
scan命令在每行上查找三个字段,一个文本字段和两个十进制整数字段。匹配行报告找到的三个字段,空行或仅包含文本报告的行。如果找到匹配项,则会将其添加到结果中。
<强> ETA:强>
要处理您在评论中提到的真实日志文件:
foreach line [split $data \n] {
if {[scan $line {%59[ #()-./0-9:=>A-Za-z]%s %d %d} header stuff min max] eq 4} {
set result([string trim $header]) $min-$max
}
}
(请注意,重复的标题会在数组中压缩为一个。)
如果字段中有空格,则无法使用%s
使用数据。相反,您可以使用
% set chars [string map {\n {}} [join [lsort -unique [split $data {}]] {}]]
#()-./0123456789:=>ABCDEFGHILMNOPRSTUVWXY[]abcdefghijklmnopqrstuvwxyz
易于简化现场规范
[ #()-./0-9:=>A-Za-z]
如果你需要能够匹配括号,请将它们放入:
[][ #()-./0-9:=>A-Za-z]
要分割包含大写文本和空白的行,那么只有等号和可能更多的空格直到行尾,
package require textutil::split
::textutil::splitx $data {(?n)^[[:upper:] ]+=+\s*$}
文档: eq (operator), foreach, if, join, lsort, package, parray, regexp, Syntax of Tcl regular expressions, scan, set, split, string, textutil::split (package)
答案 1 :(得分:0)
代码段:
set foo {
Info in log files:
Trace Header Min Max Mean
aaa 1 6 xx
bbb 2 7 xxx
}
set pattern {^(.*)\s+(\d+)\s+(\d+)\s+.*$}
set result [regexp -line -inline -all -- $pattern $foo]
array set bar {}
puts "Here's one view..."
foreach {all item min max} $result {
puts "$item $min-$max"
set bar([string trim $item]) $min-$max
}
puts ""
puts "Here's another one..."
puts [join [lsort [array names bar]] "\t"]
foreach item [lsort [array names bar]] {
puts -nonewline "$bar($item)\t"
}
执行输出:
Here's one view...
aaa 1-6
bbb 2-7
Here's another one...
aaa bbb
2-7 1-6