我有一个文件包含带有文件路径的行。有时路径包含SHELL环境变量,我想检查文件是否存在。 以下是我的解决方案:
set fh [open "the_file_contain_path" "r"]
while {![eof $fh]} {
set line [gets $fh]
if {[regexp -- {\$\S+} $line]} {
catch {exec /usr/local/bin/tcsh -c "echo $line" } line
if {![file exists $line]} {
puts "ERROR: the file $line is not exists"
}
}
}
我确定没有使用
有更优雅的解决方案/ usr / local / bin / tcsh - c
答案 0 :(得分:3)
您可以在regexp命令中捕获变量名称,并在Tcl的全局env
数组中进行查找。此外,您使用eof
作为while条件意味着您的循环将进行一次太多的交互(请参阅http://phaseit.net/claird/comp.lang.tcl/fmm.html#eof)
set fh [open "the_file_contain_path" "r"]
while {[gets $fh line] != -1} {
# this can handle "$FOO/bar/$BAZ"
if {[string first {$} $line] != -1} {
regsub -all {(\$)(\w+)} $line {\1::env(\2)} new
set line [subst -nocommand -nobackslashes $new]
}
if {![file exists $line]} {
puts "ERROR: the file $line does not exist"
}
}
答案 1 :(得分:2)
首先,通常更容易(对于小文件,比如不超过1-2MB)读取整个文件并将split
分成行而不是使用gets
和{{1在eof
循环中。 (while
命令非常快。)
其次,要进行替换,您需要替换字符串中的位置,因此您使用split
。这确实意味着您需要采用更复杂的方法来进行替换,regexp -indices
和string range
可以完成一些工作。假设你正在使用Tcl 8.5 ...
string replace
答案 2 :(得分:0)
TCL程序可以使用内置的全局变量env
读取环境变量。阅读该行,查找$
后跟一个名称,查找$::env($name)
,并将其替换为变量。
如果文件由不受信任的用户提供,那么使用shell是非常糟糕的。如果他们将; rm *
放入文件中该怎么办?如果你要使用shell,你应该至少使用sh或bash,而不是tcsh。