TCL如何读取、提取和统计.txt文件(当前目录)中发生的事件

发布于 2024-08-31 02:00:57 字数 929 浏览 1 评论 0原文

我是脚本初学者,正在大力学习TCL的嵌入式系统开发。

我必须在当前目录中搜索仅具有 .txt 格式的文件,计算 .txt 文件中每个不同“Interface # nnnn”字符串的情况数,其中 nnnn 是最大 4 到 32 位的十六进制数字和 o/接口编号对照表的 p。我在编写脚本时面临实现问题,即无法实现链接列表、二维数组等数据结构。 我正在 TCL 中使用多维数组(将值传递到程序中和程序外的数组中)重写脚本,以扫描每个 .txt 文件并搜索字符串/正则表达式“Interface #”来计数并显示数字的发生次数。如果有人能帮助我完成这部分,我将不胜感激。

仅搜索 .txt 扩展名文件并获取文件的大小

这是我在当前目录中搜索 .txt 文件的代码

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

我认为这些是完成它的所有可能的逻辑步骤 i) 搜索并找到 .txt 文件后,以只读模式打开所有 .txt 文件 ii) 使用过程 (proc) Interface number to NULL 和 Interface count to Zero 0 创建数组或列表 iii) 扫描 .txt 文件并搜索字符串或正则表达式“interface # iv) 当在 .txt 文件中找到匹配项时,检查接口编号并增加相应条目的计数。否则将新元素添加到接口编号列表中 v) 如果没有文件返回到第一个目录

我的o/p如下

Interface    Frequency
123f            3
1232            4

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

若相惜即相离 2024-09-07 02:00:57

编辑为按名称使用数组而不是全局变量。

我认为您会想要类似的东西。您可以对每个文件调用 scan_for_interface,并在最后调用 print_report。您可以更高级,并将其包装在 Itcl 类或 命名空间scan_for_interface 的第二个参数是存储结果的数组的名称,该名称将传递给 print_reportregexp 链接将描述 regexp 的工作原理:

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)"
  }
}

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)"
  }
}
所谓喜欢 2024-09-07 02:00:57

我不是全局变量的忠实粉丝,我会选择 Trey 使用的东西,但让它返回当前文件结果的字典(或数组获取),并将它们合并到维护在的字典(或数组)中呼叫者级别。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文