我在這裏有一個文件,它有多個set語句。但是,我想提取我感興趣的內容。可以將下面的代碼幫助用Tcl解析文件
set in [open filename r]
seek $in 0 start
while{ [gets $in line ] != -1} {
regexp (line to be extracted)
}
我在這裏有一個文件,它有多個set語句。但是,我想提取我感興趣的內容。可以將下面的代碼幫助用Tcl解析文件
set in [open filename r]
seek $in 0 start
while{ [gets $in line ] != -1} {
regexp (line to be extracted)
}
首先,你不需要seek
到打開一個文件進行讀取後開始直線;這就是它開始的地方。
其次,用於讀取文件中的模式是這樣的:
set f [open $filename]
while {[gets $f line] > -1} {
# Process lines
if {[regexp {^set +(\S+) +(.*)} $line -> name value]} {
puts "The name \"$name\" maps to the value \"$value\""
}
}
close $f
OK,這中間有一個很簡單的RE(和更復雜的文件,你需要一些),但是那一般模式。請注意,與Tcl一樣,while
命令字之後的空格很重要,while表達式和while body之間的空格也很重要。有關特定類型的輸入數據使用什麼RE的具體幫助,請在Stack Overflow上提出進一步的問題。
其他解決方案:
而不是使用gets
我更喜歡使用read
功能來讀取文件的全部內容,然後通過處理這些行線。因此,我們在對文件操作的完全控制有它的線
set fileName [lindex $argv 0]
catch {set fptr [open $fileName r]} ;
set contents [read -nonewline $fptr] ;#Read the file contents
close $fptr ;#Close the file since it has been read now
set splitCont [split $contents "\n"] ;#Split the files contents on new line
foreach ele $splitCont {
if {[regexp {^set +(\S+) +(.*)} $ele -> name value]} {
puts "The name \"$name\" maps to the value \"$value\""
}
}
如何運行這段代碼的列表:
說上面的代碼保存在test.tcl
然後
tclsh test.tcl FileName
FileName
是文件的完整路徑,除非文件位於程序所在的同一目錄中。
錯誤:不能讀取fptr – Naaz 2011-03-28 05:20:10
提取的行是......」man.poi oa vs vs 0.9 0.09「...我不認爲該正則表達式將工作 – Naaz 2011-03-29 06:07:08
您是否在運行程序時給出了文件名作爲參數?由於打開的函數未找到該文件,因此出現錯誤。 – vaichidrewar 2011-03-30 14:41:15
這是另一個解決方案:使用Tclx的文件掃描功能。請查閱Tclx瞭解更多信息。我喜歡這個解決方案,因爲你可以有幾個scanmatch塊。
package require Tclx
# Open a file, skip error checking for simplicity
set inputFile [open sample.tcl r]
# Scan the file
set scanHandle [scancontext create]
scanmatch $scanHandle {^\s*set} {
lassign $matchInfo(line) setCmd varName varValue; # parse the line
puts "$varName = $varValue"
}
scanfile $scanHandle $inputFile
close $inputFile
又一解決方案:從fileutil包使用grep命令:
package require fileutil
puts [lindex $argv 0]
set matchedLines [fileutil::grep {^\s*set} [lindex $argv 0]]
foreach line $matchedLines {
# Each line is in format: filename:line, for example
# sample.tcl:set foo bar
set varName [lindex $line 1]
set varValue [lindex $line 2]
puts "$varName = $varValue"
}
是否可能在TCL中使用腳本代替TCLx – Naaz 2011-03-28 05:14:26
@Nazeeb:這仍然是TCL,但是在Tclx包的幫助下。如果您不想使用Tclx,請查看其他解決方案。我希望我能正確理解你的問題。 – 2011-03-28 15:10:27
到目前爲止,我已閱讀您的評論,如果我正確理解您的輸入數據文件有6(或9,取決於哪個評論)每行數據字段,用空格分隔。您想使用正則表達式將它們解析爲6個(或9個)數組或列表,每個數據字段一個。
如果是的話,我會嘗試這樣的事情(使用列表):
set f [open $filename]
while {[gets $f line] > -1} {
# Process lines
if {[regexp {(\S+) (\S+) (\S+) (\S+) (\S+) (\S+)} $line -> name source drain gate bulk inst]} {
lappend nameL $name
lappend sourceL $source
lappend drainL $drain
lappend gateL $gate
lappend bulkL $bulk
lappend instL $inst
}
}
close $f
現在你應該有一組6名名單,每場之一,在列表中的一個條目每個項目你的輸入文件。例如,要訪問第i個名稱,請抓住$nameL[$i
]。
如果(我懷疑),你的主要目標是讓他的名字是「foo」的設備的參數,你會使用這樣的結構:
set name "foo"
set i [lsearch $nameL $name]
if {$i != -1} {
set source $sourceL[$i]
} else {
puts "item $name not found."
set source ''
# or set to 0, or whatever "not found" marker you like
}
set File [ open $fileName r ]
while { [ gets $File line ] >= 0 } {
regex {(set) ([a-zA-Z0-0]+) (.*)} $line str1 str2 str3 str4
#str2 contains "set";
#str3 contains variable to be set;
#str4 contains the value to be set;
close $File
}
感謝名單4回合的幫助........ ill c 2 it ..... – Naaz 2011-03-25 10:29:47
我有如下幾行...... set name some string set othername some otherstring .... and soon – Naaz 2011-03-25 10:41:02
@ Nazeeb:嘗試上面更改的版本。拆分這些行以便獲得'$ name'和'$ value'。我的樣品只是將它們打印出來;添加代碼來做一些更聰明的... – 2011-03-25 10:46:16