如何将文件拆分为列表列表TCL

时间:2017-11-06 08:32:46

标签: tcl

我正在编写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并拆分但没有成功

3 个答案:

答案 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}]
}

请注意,这是在构建一个数组;长期经验说调用变量list1list2,...,当你在循环中构建它们时是一个坏主意,并且应该使用数组,有效地提供像{{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

文档: arrayforeachincrlappendlindexlmap (for Tcl 8.5)lmapparraysetsplitstring

答案 2 :(得分:-1)

该代码适用于Windows:

TCL文件代码是:

&#13;
&#13;
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;
&#13;
&#13;

thext文件代码是:

&#13;
&#13;
cctv=Integrated Webcam

resolutionX=1920
resolutionY=1080

imagePrefix=ImageCapture
imageFormat=jpg
folderPath=c:/test/

//camera=video=Integrated Webcam,Logitech HD Webcam C525
&#13;
&#13;
&#13;

这段代码对我有用,我接受来自文本文件的代码被传递的参数列表。