1

ファイルへのパスを含む行を含むファイルがあります。パスに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

4

3 に答える 3

3

regexpコマンドで変数名をキャプチャし、Tclのグローバルenv配列でルックアップを実行できます。また、eofwhile条件として使用すると、ループが1回だけ相互作用することになります(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"
  }
}
于 2012-09-01T12:12:37.073 に答える
2

まず、通常は、ループ内splitで使用するよりも、ファイル全体とそれを行に読み込む方が簡単です(たとえば、1〜2MB以下の小さなファイルの場合)。(コマンドは非常に高速です。)getseofwhilesplit

次に、置換を行うには、置換する文字列内の場所が必要なので、を使用しますregexp -indices。つまり、一部の作業を行い、一部の作業を行うには、もう少し複雑なアプローチをとる必要がありstring rangeますstring replace。Tcl8.5を使用していると仮定すると…</p>

set fh [open "the_file_contain_path" "r"]

foreach line [split [read $fh] "\n"] {
    # Find a replacement while there are any to do
    while {[regexp -indices {\$(\w+)} $line matchRange nameRange]} {

        # Get what to replace with (without any errors, just like tcsh)
        set replacement {}
        catch {set replacement $::env([string range $line {*}$nameRange])}

        # Do the replacement
        set line [string replace $line {*}$matchRange $replacement]
    }

    # Your test on the result
    if {![file exists $line]} {
        puts "ERROR: the file $line is not exists"
    }
}
于 2012-09-02T10:12:05.703 に答える
0

TCLプログラムは、組み込みのグローバル変数を使用して環境変数を読み取ることができますenv。行を読み、$名前が続くのを探し、検索し$::env($name)、それを変数の代わりに使用します。

ファイルが信頼できないユーザーによって提供されている場合、これにシェルを使用することは非常に悪いことです。彼らがファイルに入れた場合はどう; rm *なりますか?また、シェルを使用する場合は、少なくともtcshではなくshまたはbashを使用する必要があります。

于 2012-09-01T07:44:09.433 に答える