开发者

TCL How to read , extract and count the occurent in .txt file (Current Directory)

I am beginner to scripting and vigorously learning TCL for the development of embedded system.

I have to Search for the files with only .txt format in the current directory, count the number of cases of each different "Interface # nnnn" string in .txt file, where nnnn is a 4 to 32 digits max hexadecimal number and o/p of a table of Interface number against occurrence. I am facing implementation issues while writing a script i.e, Unable to implement the data structure like Linked List, Two Dimensional array. I am rewriting a script using multi dimension array (Pass values into the arrays in and out of procedure) in TCL to scan through the every .txt file and search for the the string/regular expression ‘Interface # ’ to count and display the number of occurrences. If someone could help me to complete this part will be much appreciated.

Search for only .txt extension files and obtain the size of the file

Here is my piece of code for searching a .txt file in present directory

set files [glob *.txt]
if { [llength $files] > 0 } {
    puts "Files:"
    foreach f [lsort $files] {
        puts "    [file size $f] - $f"
    }
} else {
  开发者_开发知识库  puts "(no files)"
}

I reckon these are all the possible logical steps behind to complete it i) Once searched and find the .txt file then open all .txt files in read only mode ii) Create a array or list using the procedure (proc) Interface number to NULL and Interface count to zero 0 iii) Scan thro the .txt file and search for the string or regular expression "interface # iv) When a match found in .txt file, check the Interface Number and increment the count for the corresponding entry. Else add new element to the Interface Number list v) If there are no files return to the first directory

My o/p is like follows

Interface    Frequency
123f            3
1232            4


Edited to use an array by name instead of global variable.

I think you'd want something along the lines of this. You'd call scan_for_interface on each file, and at the end call print_report. You can get fancier and wrap this in an Itcl class, or a namespace. The second argument to scan_for_interface is the name of the array in which to store the results, and that name is passed to print_report. The regexp link will describe how regexp works:

proc scan_for_interface {file arrayname} {
  upvar $arrayname array
  set fh [open $file r]
  while {[gets $fh line] >= 0} {
    if {[regexp -- {Interface # ([[:xdigit:]]{4}|[[:xdigit:]]{32})$} $line ignore num]} {
      if {[info exists array($num)]} {
        incr array($num)
      } else {
        set array($num) 1
      }
    }
  }
  close $fh
}

proc print_report {arrayname} {
  upvar $arrayname array
  puts "Interface    Frequency"
  set fmt "%s             %d"
  foreach {interface number} [array get array] {
    puts [format $fmt $interface $number]
  }
}

# the following is a proc that takes the question's code
# and incorporates the calls to the accounting functions
proc dosearch {} {
  set files [glob *.txt]
  if { [llength $files] > 0 } {
    puts "Files:"
    foreach f [lsort $files] {
      puts "    [file size $f] - $f"
      scan_for_interface $f tally
    }
    print_report tally
  } else {
    puts "(no files)"
  }
}


Not being a big fan of globals, I'd go with something like what Trey used, but have it return a dict (or array get) of the results for the current file, and merge them into a dict (or array) maintained at the caller level.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜