首页 > 解决方案 > tcl foreach 行在空格2上拆分

问题描述

如何防止该行在 foreach 处被空白分隔?

变量“开始”是“确定完成”,输出在第一行确定,第二行完成

如果我直接从 bash htkrd 开始,它会回到这里

test@home:~$ htkrd
text1 aa
text2 bb 
text3 cc
text4 dd
text5 ee
text6 ff
OK done
test@home:~$

脚本:

proc pub:test {nick host handle channel arg} {
    set start [exec bash -c "htkrd"]
    #foreach i $start {
    putnow "PRIVMSG $channel :$start"
    #}
}

错误的输出:

[28.06.20/10:11:12] <@testbot> text1 aa

正确的输出:

 <@testbot> text1
 <@testbot> text2
 <@testbot> text3
 <@testbot> text4
 <@testbot> text5
 <@testbot> text6
 <@testbot> OK done

标签: tcl

解决方案


要按换行符拆分子进程的输出,请使用split … "\n". 然后,您可以遍历每一行foreach并决定如何处理它(打印或不打印)。下面是如何跳过所有视觉上的空行,这可能是第一次尝试为 IRC 生成输出的好主意。

proc pub:test {nick host handle channel arg} {
    set start [exec bash -c "htkrd"]
    foreach line [split $start "\n"] {
        set trimmed [string trim $line]; # Remove extra whitespace
        if {$trimmed ne ""} {;           # If not empty after trimming
            putnow "PRIVMSG $channel :$trimmed"
        }
    }
}

现在,可以对线条进行更复杂的操作,但您需要非常清楚您希望它们发生什么,以便我们能够提供帮助。(问题是有几种方法可以使单词脱离一行,这样做时细节非常重要。Tcl 有许多用于字符串操作的工具。)

请注意,我很可能会在此时拆分代码,以便决定如何转换单行的代码与其他代码分开。像那样,您可以只考虑问题的那一部分,而不是一次将所有东西都覆盖在一起

proc TransformLine {line} {
    # Trivial example; remove whitespace and last two letter word if present
    set trimmed [string trim $line]
    return [regsub {\s+\w{2}$} $trimmed ""]
}

proc pub:test {nick host handle channel arg} {
    set start [exec bash -c "htkrd"]
    foreach line [split $start "\n"] {
        set processed [TransformLine $line]
        if {$processed ne ""} {
            putnow "PRIVMSG $channel :$processed"
        }
    }
}

可能可以像这样编写转换器过程:

proc TransformLine {line} {
    # Depends on the lines being well-formed Tcl lists; most input mostly is…
    if {[string length [lindex $line end]] == 2} {
        set line [lrange $line 0 end-1]
    }
    return [join $line]
}

推荐阅读