搜索特定行并使用tcl将其存储在另一个文件中

时间:2014-06-20 10:46:05

标签: parsing tcl

我必须查看一个文件log_file.txt,它看起来像这样:

*Jun 20 16:03:52.482 IST: DSL 0-FW: Data0:
*Jun 20 16:03:52.482 IST: DSL 0-FW: 0x20 0x7 
*Jun 20 16:03:52.482 IST: DSL 0-FW: Read from ID 0x369
*Jun 20 16:15:32.591 IST: DSL 0: IPC: Msg_type (4)
*Jun 20 16:15:33.591 IST: DSL 0: IPC: Msg_type (4)
*Jun 20 16:15:33.591 IST: DSL 0: IPC: Msg_type (4)
*Jun 20 16:15:33.839 IST: %LINK-3-UPDOWN: Interface changed state to down
*Jun 20 16:06:21.848 IST: DSL 0-FW: PHY: ack_control: id:0x1
*Jun 20 16:06:21.848 IST: DSL 0-FW: PHY: ackcontrol: 
*Jun 20 16:06:22.192 IST: DSL 0-FW: PHY: ack_control:

在这里,我必须搜索包含DSL 0-FW:的行,并将该行存储在另一个文件中。但我必须排除DSL 0-FW: PHY的那些。 有可能这样做吗?

2 个答案:

答案 0 :(得分:0)

您可以逐行阅读文件,并使用string first过滤其他文件中需要的行。 string first将特定较小字符串的位置返回到较大的字符串中。如果找不到较小的字符串,则返回-1

# Assuming that the script is in the same directory as the file... otherwise 
# replace by the file path

# Read the log file
set fin [open "log_file.txt" r]
# Open a file for writing
set fout [open "output.txt" w]

# Read line by line
while {[gets $fin line] != -1} {
    # Check if "DSL 0-FW:" is in the line, if found, proceed
    if {[string first "DSL 0-FW:" $line] != -1} {

        # Check if "DSL 0-FW:" is in the line, if not found, proceed
        if {[string first "DSL 0-FW: PHY" $line] == -1} {
            puts $fout $line
        }
    }
}

close $fin
close $fout

或者您也许可以使用正则表达式:

while {[gets $fin line] != -1} {
    # Check if "DSL 0-FW:" without " PHY" is in the line, if found, proceed
    if {[regexp -- {DSL 0-FW:(?! PHY)} $line]} {
        puts $fout $line
    }
}

DSL 0-FW:(?! PHY)如果DSL 0-FW:后面没有 PHY,则匹配{。}}。


实际上,您甚至可以使用string match

while {[gets $fin line] != -1} {
    # Check if "DSL 0-FW:" is in the line, if found, proceed
    if {[string match "DSL 0-FW:" $line]} {

        # Check if "DSL 0-FW:" is in the line, if not found, proceed
        if {![string match "DSL 0-FW: PHY" $line]} {
            puts $fout $line
        }
    }
}

答案 1 :(得分:0)

假设将整个日志文件读入内存不是问题:

set all [split [read -nonewline "log.file"] \n]
set wanted [lsearch -all -inline -regex {DSL 0-FW: (?!PHY:)} $lines]
set fh [open "partial.file" w]
puts $fh [join $wanted \n]
close $fh

这使用负向前瞻来过滤掉您不想要的行:http://tcl.tk/man/tcl8.5/TclCmd/re_syntax.htm#M25