如何使用TCL从文件中提取所需的行?

时间:2016-06-18 13:00:55

标签: tcl

我的文件如下所示。我想从文件中仅提取id,pos和type,以便我可以进一步使用它。我是否需要将此数据视为列表并使用lindex语法进行检索。

{particles {id pos type v f}     {0 442.3601602032813 775.8494355067412 339.7428247245854 0 -1.0649468656691174 0.3118359585805807 0.7974629587243917 -7.856415738784473 120.82920096524781 80.7680149353967}     {1 75.78431491144367 187.28007812237516 279.3569202413006 0 0.3317344469183915 3.0716559473604916 -1.679965732986453 2.573367640795655 -11.46026754809828 125.75306472245369}     {2 44.167251258358164 371.8839725825084 80.32709197838003 0 -0.6260768510694417 0.9493261445672099 0.9445444874655268 -98.8132600015945 -80.10617403827258 43.578514821777155}     {3 289.0168944249348 193.4364952458922 96.30251497465443 0 -0.5327035586676473 1.028492567403681 4.364969924730662 139.09290151549465 75.46717320097427 -29.955066397359094}     {4 324.94257366360085 404.9215380451672 799.3481016151578 0 -1.2801842708841038 -4.320355658821216 2.9394195915181567 -109.72971491904342 -44.06068452005151 118.2802261191011}     {5 598.4521733790556 447.74320547029174 750.4399422142899 0 1.740414834859398 -0.5926143788565617 1.5937397085063156 -155.08309023301794 186.08101953841978 177.1804659692657} }

这是我在下面使用的代码。谁能告诉我我使用的代码是否正确。

set num_part 6
set mol1 0.1666
set mol2 0.8333
set num_conf 2
for {set i 0} {$i < $num_conf} {incr i} {
set f [open "config_$i" "r"]
set part [while { [blockfile $f read auto] != "eof" } {} ]
set g [open "positions" "w"]
blockfile $g write particles {id pos type}
close $f
close $g
set g [open "positions" "r"]
set data [read $g]
close $g
set num0 0
for {set j 0} {$j < [expr { $num_part + 1 }]} {incr j} {
    set type [lindex $data 0 $j 4]
    if { $type == 0 } {
        set tlist [expr $i]
        set x0 [lindex $data 0 $j 1]
        set y0 [lindex $data 0 $j 2]
        set z0 [lindex $data 0 $j 3]
        set total1 [ expr { sqrt(($x0 * $x0) + ($y0 * $y0)+ ($z0 * $z0)) }]+0]
        incr num0
        puts " $i :: $num0 "
        set dum 0
        for {set k 0} {$k < [expr { $num_part + 1 }]} {incr k} {
            set type [lindex $data 0 $k 4]
            if { $type == 1 } {
                set tlist [expr $i]
                set x1 [lindex $data 0 $k 1]
                set y1 [lindex $data 0 $k 2]
                set z1 [lindex $data 0 $k 3] 
                set total2 [ expr { sqrt(($x1 * $x1) + ($y1 * $y1)+ ($z1 * $z1)) }]+0]
                incr dum
                puts " $i :: $dum "
                }
            }   
        }   
    }
}
set h [open "dist12" "w"]
set dist12 [ expr {($mol1 * $total1)-($mol2 * $total2)}]
puts "Distance between cross particles $dist12"
puts $h "\#   t  $dist12 "
foreach t $tlist dist" $dist12  { puts $h "$t $dist_12" } 
close $h

1 个答案:

答案 0 :(得分:1)

你有几行看起来很可疑。

1

set part [while { [blockfile $f read auto] != "eof" } {} ]

while的结果是一个空字符串,所以上面的代码可能没有按你的意愿行事。不太确定如何解决它; blockfile不是标准的Tcl命令。

2:

for {set j 0} {$j < [expr { $num_part + 1 }]} {incr j} {

不是正确性问题,但可以写成:

for {set j 0} {$j < $num_part + 1} {incr j} {

生成的字节码实际上是相同的,但它更短,更容易阅读。

3:

set tlist [expr $i]

这看起来不必要和可疑。我们知道i是一个数值变量(实际上它包含一个整数),因此不需要假装它是一个表达式。它减慢了速度,没有任何好处。

你有两次这样做。

4:

set total1 [ expr { sqrt(($x0 * $x0) + ($y0 * $y0)+ ($z0 * $z0)) }]+0]

这一行肯定是错的。 ]个字符的数量与[个字符的数量不匹配,因此您获得的内容将是“意外”,+0无效或有害。最好写一个程序来帮助你解决这个问题。将程序放在脚本的顶部。

proc length {x y z} {
    expr { sqrt($x*$x + $y*$y + $z*$z) }
}

然后稍后再打电话:

set total1 [length $x0 $y0 $z0]

同样适用于total2之后的计算。

5:

foreach t $tlist dist" $dist12  { puts $h "$t $dist_12" } 

看起来这有一个拼写错误:dist"而不是dist。在循环中使用dist的失败也看起来很奇怪;我觉得你在这里出错了,应该再看看,想想你真正想做的事情。