我有一个文件somefile.txt,其中包含如下行:
{ abc1 } 1
{ cde1 } 101
{ fgh1 } 1
{ ijk1 } 2
这是一个非常大的文件。我只想找出第一行和第三行并计数。我已经尝试使用正则表达式和lsearch(将其转换为列表)通过 {\s\}\s1\n}
,但不起作用。我该怎么办...?
我也尝试过{\s\}\s1}
,但它会打印所有4行。
我有一个文件somefile.txt,其中包含如下行:
{ abc1 } 1
{ cde1 } 101
{ fgh1 } 1
{ ijk1 } 2
这是一个非常大的文件。我只想找出第一行和第三行并计数。我已经尝试使用正则表达式和lsearch(将其转换为列表)通过 {\s\}\s1\n}
,但不起作用。我该怎么办...?
我也尝试过{\s\}\s1}
,但它会打印所有4行。
解决方案1:如果您不想使用regexp
,并且您的输入行具有与{string} number
相同的格式
set fd [open "somefile.txt" r]
while {[gets $fd line] >= 0} {
if {[lindex $line 1] == 1} {
puts [lindex $line 1] ;# Prints only 1
puts $line ;# Prints Whole Line which has 1 at end
}
}
解决方案2:如果您想使用regexp
,那么请使用group-capturing
,即(.*)
set fd [open "somefile.txt" r]
while {[gets $fd line] >= 0} {
if {[regexp "\{.*\} (.*)" $line match match1]} {
if {$match1 == 1} {
puts $line
}
}
}
regexp
的建议。set fd [open "somefile.txt" r]
while {[gets $fd line] >= 0} {
if {[regexp {\d+$} $line match]} {
if {$match == 1} {
puts $match ;# Prints only 1
puts $line ;# Prints whole line which has 1 at end
}
}
}
regexp {\d+$} $line match
,然后将 $match
与 1 进行比较。 - Peter Lewerin你似乎需要捕获第一行和第三行末尾的数字。
以下是实现此目的的方法:
set s {{ abc1 } 1
{ cde1 } 101
{ fgh1 } 1
{ ijk1 } 2}
set re {^{[^{}]*}\s*(\d+)\s+{[^{}]*}\s*\d+\s+{[^{}]*}\s*(\d+)}
regexp $re $s m g1 g2
set res [expr $g1 + $g2]
puts $res
请查看IDEONE演示
模式匹配:
^
- 字符串的开头{[^{}]*}
- 一个类似于{...}
的字符串,其中没有括号\s*
- 0个或多个空格(\d+)
- 第1组(g1
)捕获1个或多个数字\s+
- 1个或多个空格(如果前后没有尾随/前导空格,则可以用[\r\n]+
替换){[^{}]*}\s*\d+\s+{[^{}]*}\s*(\d+)
- 参见上文,只是(\d+)
将创建第二个变量g2
。请查看正则表达式演示
package require fileutil
::fileutil::foreachLine line somefile.txt {
if {[lindex $line end] == 1} {
puts $line
}
}
这个解决方案查看文件中的每一行,并检查最后一个项目是否等于1。如果是,则打印该行。
您还可以对它们进行计数/求和:
set count 0
set sum 0
::fileutil::foreachLine line somefile.txt {
if {[lindex $line end] == 1} {
puts $line
incr count
incr sum [lindex $line end] ;# yeah, I know, always 1
}
}
puts "Number of lines: $count"
puts "Sum of items: $sum"
fileutil
,或者您不能或不想安装它,您可以使用更低级别的核心等效功能:set f [open somefile.txt]
while {[gets $f line] >= 0} {
if {[lindex $line end] == 1} {
puts $line
}
}
close $f
::fileutil::foreachLine line somefile.txt {
if {[regexp {\m1$} $line]} {
puts $line
}
}
这个正则表达式可以找到以数字1结尾的单词(即在它前面没有数字或单词字符)。
文档:close,fileutil 包,gets,if,lindex,open,package,puts,Tcl 正则表达式语法,regexp,while
fileutil
在所有平台上都可用,但可能需要安装。 - Peter Lewerinfileutil
。如果你正在使用tclsh 8.5,那么它是内置的。 - toxic_boi_8041