我的文件如下所示。我想从文件中仅提取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
答案 0 :(得分:1)
你有几行看起来很可疑。
set part [while { [blockfile $f read auto] != "eof" } {} ]
while
的结果是一个空字符串,所以上面的代码可能没有按你的意愿行事。不太确定如何解决它; blockfile
不是标准的Tcl命令。
for {set j 0} {$j < [expr { $num_part + 1 }]} {incr j} {
不是正确性问题,但可以写成:
for {set j 0} {$j < $num_part + 1} {incr j} {
生成的字节码实际上是相同的,但它更短,更容易阅读。
set tlist [expr $i]
这看起来不必要和可疑。我们知道i
是一个数值变量(实际上它包含一个整数),因此不需要假装它是一个表达式。它减慢了速度,没有任何好处。
你有两次这样做。
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
之后的计算。
foreach t $tlist dist" $dist12 { puts $h "$t $dist_12" }
看起来这有一个拼写错误:dist"
而不是dist
。在循环中使用dist
的失败也看起来很奇怪;我觉得你在这里出错了,应该再看看,想想你真正想做的事情。