在tcl中删除文件中两个感兴趣的实例之间的行

在tcl中删除文件中两个感兴趣的实例之间的行,tcl,Tcl,早些时候,我请求了一些帮助来删除和替换文件的内容。在彼得的帮助和示范下,问题解决了()。但是它创建了另一个,这个问题与删除行有关 问题是,我可以删除文件中出现的前缀_1的每个实例的行 但是,两个实例之间有跳过的行(因为该行不以前缀_1开头),因此保留在文件中 我知道这行代码以前缀_1开头,后跟一个点,然后是变量名,最后是空格、等号或冒号 以冒号结尾的每一行都有一个与之关联的表 我会识别两类线,一类以空格和等号结尾,另一类以冒号结尾。然后,每当检测到冒号时,是否删除所有行,直到检测到前缀_1的下一

早些时候,我请求了一些帮助来删除和替换文件的内容。在彼得的帮助和示范下,问题解决了()。但是它创建了另一个,这个问题与删除行有关

问题是,我可以删除文件中出现的前缀_1的每个实例的行

但是,两个实例之间有跳过的行(因为该行不以前缀_1开头),因此保留在文件中

我知道这行代码以前缀_1开头,后跟一个点,然后是变量名,最后是空格、等号或冒号

以冒号结尾的每一行都有一个与之关联的表

我会识别两类线,一类以空格和等号结尾,另一类以冒号结尾。然后,每当检测到冒号时,是否删除所有行,直到检测到前缀_1的下一个实例

Prefix_1.Var1 = -2
Prefix_1.Var2 = 1
Prefix_1.Var3:
    1.1 1.3 1.8 15 1.9 0.1 16 71 31 16 12 1 881 199 19 100 1000 1005 1005 1005
Prefix_1.Var4 = 1
Prefix_1.Var5:
    40 50 75 100 150
Prefix_1.Var6:
    4
    7
    15
    25
    35
    45
Prefix_1.Var7:
    #TABLE 30 2 5 6
    70       70       70       70       70       100      100
    81       80       80       100      100      81       80
    80       100      100      81       80       80       100
    100      82       81       81       100      100      87
    87       87
Prefix_1.Var8 = 1
Prefix_1.Var9 = 65
Prefix_1.Var10:
    255 255 255 255 255 255 255 255 255 255
Prefix_1.Var11:
    0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 2 6 1 2 2 0 0 0 0 0 0 0 0
Prefix_1.Var12 = 30
删除了所有带有前缀_1的行之后,我仍然保留了这些位于前缀_1的两个实例之间的行

我也想删除这些

1.1 1.3 1.8 15 1.9 0.1 16 71 31 16 12 1 881 199 19 100 1000 1005 1005 1005
40 50 75 100 150
4
7
15
25
35
45
#TABLE 30 2 5 6
70       70       70       70       70       100      100
81       80       80       100      100      81       80
80       100      100      81       80       80       100
100      82       81       81       100      100      87
87       87
255 255 255 255 255 255 255 255 255 255
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 2 1 2 6 1 2 2 0 0 0 0 0 0 0 0
(这个答案扩展了我的理解。)

简单修复:替换

    default {
        lappend buf $line
    }

如果您使用的是
upvar
变量,或

    default {
        return $line
    }

否则

这意味着默认操作是跳过一行,并且仅当行具有除“prefix_1”之外的编号前缀时,才会保留该行

这个解决方案不符合文件中的数据语法,这是不令人满意的,但如果它能工作,应该足够好了

计算前缀_1的出现次数

您可以记录以“Prefix_1”开头的第一行和最后一行的行号,但要做到这一点,您需要在处理命令之外保留更多的数据。现在可能是转向面向对象编程的好时机

oo::class create LineProcessor {
    variable first last count buffer
    constructor args {
        set first 0
        set last 0
        set count 0
        set buffer {}
    }
    method process line {
        incr count
        switch -regexp $line {
            {^Prefix_1\.} {
                if {$first == 0} {
                    set first $count
                }
                set last $count
                return {}
            }
            {^Prefix_2\.} {
                lappend buffer [regsub 2 $line 999]
            }
            {^Prefix_} {
                lappend buffer $line
            }
            default {}
        }
    }
    method dump {} {
        join $buffer \n
    }
    method report {} {
        puts "First/last line with Prefix_1: $first/$last"
    }
}

LineProcessor create lp

fileutil::foreachLine line data.txt {
    lp process $line
}
fileutil::writeFile data.txt [lp dump]
lp report
# => First/last line with Prefix_1: 1/40

此代码与以前大致相同,只是在“Prefix_1”的子句中使用了一些逻辑来记录行号,并且支持变量封装在一个对象中,而不是全局数据。

一般策略:将文件拆分为块,其中每个块都将被保留或删除。然后为每个区块决定是否保留它。分块策略恰好不是“拆分为单行”…所以-除了regsub 2到999之外,您还想删除所有prefix1数据,对吗?我添加了文件处理前后的示例我不理解您的问题。正如我所读到的,您的示例输入中的每一行都应该删除。不幸的是,它并没有删除每一行,我将再试一次并得到回复。谢谢Peter,这在某种程度上是有效的。我想我可以把它扩展一点。顺便问一下,是否有可能在文件中第一次和最后一次出现“Prefix_1”时找出行号?我可以计算模式出现的次数和文件中的总行数,但无法可靠地获得Perfix_1出现的第一次和最后一次时间。
    {^Prefix_} {
        return $line
    }
    default {}
oo::class create LineProcessor {
    variable first last count buffer
    constructor args {
        set first 0
        set last 0
        set count 0
        set buffer {}
    }
    method process line {
        incr count
        switch -regexp $line {
            {^Prefix_1\.} {
                if {$first == 0} {
                    set first $count
                }
                set last $count
                return {}
            }
            {^Prefix_2\.} {
                lappend buffer [regsub 2 $line 999]
            }
            {^Prefix_} {
                lappend buffer $line
            }
            default {}
        }
    }
    method dump {} {
        join $buffer \n
    }
    method report {} {
        puts "First/last line with Prefix_1: $first/$last"
    }
}

LineProcessor create lp

fileutil::foreachLine line data.txt {
    lp process $line
}
fileutil::writeFile data.txt [lp dump]
lp report
# => First/last line with Prefix_1: 1/40