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

Parsing 使用tcl搜索特定行并将其存储在另一个文件中,parsing,tcl,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

我必须查看一个文件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:
在这里,我必须搜索包含
dsl0-FW:
的行,并将该行存储在另一个文件中。但是我必须排除那些带有
dsl0-FW:PHY
的。
是否有可能做到这一点?

您可以逐行读取该文件,并使用筛选其他文件中需要的行
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
或者您也可以使用regexp:

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


实际上,您甚至可以使用
字符串匹配

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
        }
    }
}

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

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

这使用了一个负前瞻来过滤掉你不想要的行:

第一行有效:D没有尝试其他行。谢谢我想知道,在将一行复制到其他文件后,是否有什么东西可以从第一行中删除该行。@aro没问题,我添加了其他行作为替代,因此最终是您的pick=Pand doesnt,在第二行之前
,而
注释应该是
检查DSL 0-FW:PHY:
是否在行中?@aro No,这个评论就是我的本意。第二次检查时需要进行一次检查。它可能不那么容易理解,但它较短。所以,这一切都取决于你是否希望你的代码更易于维护,或者更短,但你知道你以后会理解其中的内容,因为
regexp
本质上不是所有人都容易理解的,但如果你这样做,在适当的地方使用它并没有错。哦,是的,我明白了。。谢谢在复制到第二个文件后,有没有办法删除第一个文件中的行?