我正在编写TCL,我想将一个文件分成两个列表列表, 该文件包含:
(1,2) (3,4) (5,6)
(7,8) (9,10) (11,12)
我希望得到两个清单 每行一个,包含每个包含两个数字的列表
例如:
puts $list1 #-> {1 2} {3 4} {5 6}
puts [lindex $list1 0] #-> 1 2
puts [lindex $list2 2] #-> 11 12
我尝试使用regexp并拆分但没有成功
答案 0 :(得分:3)
使用regexp
的想法很好,但您需要对其输出进行一些后处理。
# This is what you'd read from a file
set inputdata "(1,2) (3,4) (5,6)\n(7,8) (9,10) (11,12)\n"
foreach line [split $inputdata "\n"] {
# Skip empty lines.
# (I often put a comment format in my data files too; this is where I'd handle it.)
if {$line eq ""} continue
# Parse the line.
set bits [regexp -all -inline {\(\s*(\d+)\s*,\s*(\d+)\s*\)} $line]
# Example results of regexp:
# (1,2) 1 2 (3,4) 3 4 (5,6) 5 6
# Post-process to build the lists you really want
set list([incr idx]) [lmap {- a b} $bits {list $a $b}]
}
请注意,这是在构建一个数组;长期经验说调用变量list1
,list2
,...,当你在循环中构建它们时是一个坏主意,并且应该使用数组,有效地提供像{{1}这样的变量},list(1)
,...,因为这会产生更低的错误率。
另一种方法是使用更简单的正则表达式,然后list(2)
解析结果。当数字不仅仅是数字字符串时,这可能更有效。
scan
如果您没有使用Tcl 8.6,那么您还没有foreach line [split $inputdata "\n"] {
if {$line eq ""} continue
set bits [regexp -all -inline {\([^()]+\)} $line]
set list([incr idx]) [lmap substr $bits {scan $substr "(%d,%d)"}]
}
。在这种情况下,你会做这样的事情:
lmap
foreach line [split $inputdata "\n"] {
if {$line eq ""} continue
set bits [regexp -all -inline {\(\s*(\d+)\s*,\s*(\d+)\s*\)} $line]
set list([incr idx]) {}
foreach {- a b} $bits {
lappend list($idx) [list $a b]
}
}
答案 1 :(得分:1)
你已经有了一个答案,但它实际上可以做得更简单一点(或至少没有regexp
,这通常是一件好事。)
与Donal一样,我认为这是从文件中读取的文本:
set lines "(1,2) (3,4) (5,6)\n(7,8) (9,10) (11,12)\n"
清理一下,删除数据前后的括号和任何空格:
% set lines [string map {( {} ) {}} [string trim $lines]]
1,2 3,4 5,6
7,8 9,10 11,12
使用良好的老式Tcl实现这一目标的一种方法,产生一个名为lineN
的变量集群,其中 N 是一个整数1,2,3 ...:< / p>
set idx 0
foreach lin [split $lines \n] {
set res {}
foreach li [split $lin] {
lappend res [split $li ,]
}
set line[incr idx] $res
}
这样的双重迭代结构(多行,每行都有一对数字用单个逗号分隔),在另一行中使用一个foreach
很容易处理。变量res
用于在组装时存储结果行。在最里层,这些对被拆分并列表附加到结果中。对于每个完成的行,创建一个变量来存储结果:它的名称由字符串&#34; line&#34;和越来越多的指数。
正如Donal所说,使用变量集群并不是一个好主意。将它们收集到一个数组中会更好(相同的代码,除了命名结果变量的方式):
set idx 0
foreach lin [split $lines \n] {
set res {}
foreach li [split $lin] {
lappend res [split $li ,]
}
set line([incr idx]) $res
}
如果你有一个数组的结果,你可以使用parray
实用程序命令一举列出它们:
% parray line
line(1) = {1 2} {3 4} {5 6}
line(2) = {7 8} {9 10} {11 12}
(请注意,这是打印输出,而不是函数返回值。)
你可以从这个结果得到整行:
% set line(1)
{1 2} {3 4} {5 6}
或者您可以访问对:
% lindex $line(1) 0
1 2
% lindex $line(2) 2
11 12
如果您拥有lmap
命令(或替换为以下链接),您可以稍微简化解决方案(您不需要res
变量):
set idx 0
foreach lin [split $lines \n] {
set line([incr idx]) [lmap li [split $lin] {
split $li ,
}]
}
更简单的是让结果成为嵌套列表:
set lineList [lmap lin [split $lines \n] {
lmap li [split $lin] {
split $li ,
}
}]
您可以访问与上述类似的部分结果:
% lindex $lineList 0
{1 2} {3 4} {5 6}
% lindex $lineList 0 0
1 2
% lindex $lineList 1 2
11 12
文档: array, foreach, incr, lappend, lindex, lmap (for Tcl 8.5), lmap, parray, set, split, string
答案 2 :(得分:-1)
该代码适用于Windows:
TCL文件代码是:
proc captureImage {} {
#open the image config file.
set configFile [open "C:/main/image_config.txt" r]
#To retrive the values from the config file.
while {![eof $configFile]} {
set part [split [gets $configFile] "="]
set props([string trimright [lindex $part 0]]) [string trimleft [lindex $part 1]]
}
close $configFile
set time [clock format [clock seconds] -format %Y%m%d_%H%M%S]
set date [clock format [clock seconds] -format %Y%m%d]
#create the folder with the current date
set folderPath $props(folderPath)
append folderDate $folderPath "" $date "/"
set FolderCreation [file mkdir $folderDate]
while {0} {
if { [file exists $date] == 1} {
}
break
}
#camera selection to capture image.
set camera "video"
append cctv $camera "=" $props(cctv)
#set the image resolution (XxY).
set resolutionX $props(resolutionX)
set resolutionY $props(resolutionY)
append resolution $resolutionX "x" $resolutionY
#set the name to the save image
set imagePrefix $props(imagePrefix)
set imageFormat $props(imageFormat)
append filename $folderDate "" $imagePrefix "_" $time "." $imageFormat
set logPrefix "Image_log"
append logFile $folderDate "" $logPrefix "" $date ".txt"
#ffmpeg command to capture image in background
exec ffmpeg -f dshow -benchmark -i $cctv -s $resolution $filename >& $logFile &
after 3000
}
}
captureImage
&#13;
thext文件代码是:
cctv=Integrated Webcam
resolutionX=1920
resolutionY=1080
imagePrefix=ImageCapture
imageFormat=jpg
folderPath=c:/test/
//camera=video=Integrated Webcam,Logitech HD Webcam C525
&#13;
这段代码对我有用,我接受来自文本文件的代码被传递的参数列表。