Reputation: 25
I have a file with some thousands lines with the below format:
1.3.111.2.802.1.1.3.1.6.3.1.2.5.1.2 2 5
Upvotes: 1
Views: 114
Reputation: 246807
This uses a regular expression to capture the digits following the last dot, instead of split
s and lindex
s
set in [open $inputfile r]
set out [open $output w]
while {[gets $in line] != -1} {
if {[string match {CKSUM*} $line]} then continue
# capture the digits following the last dot
if {[regexp {.*\.(\d+)} $line -> key] && 0 <= $key && $key <= 8919} {
puts $out $line
}
}
close $in
close $out
Upvotes: 1
Reputation: 137567
Well, in this case we can try treating each line as a list; the lines seem to be well-formed enough for that (is that first field an OID?)
while {[gets $inChannel line] >= 0} {
if {[llength $line] <= 1 || [tcl::mathop::<= 0 [lindex $line end] 8191]} {
puts $outChannel $line
}
}
The tricky bit here is the use of tcl::mathop::<=
, which is the command form of the <=
expression operator, which allows us to check whether the value (from the last word of the line) is in the range 0 to 8191 without needing to repeat ourselves.
A more cautious approach would be this:
while {[gets $inChannel line] >= 0} {
if {[catch {llength $line} length] || $length <= 1} {
# Ill-formed and short lines get copied
puts $outChannel $line
continue
}
set value [lindex $line end]
if {![string is integer -strict $value]} {
# Lines with non-integers get copied
puts $outChannel $line
continue
}
if {[tcl::mathop::<= 0 $value 8191]} {
# Lines with values in range get copied
puts $outChannel $line
}
}
It's possible to not repeat the puts
but the resulting code is less clear in my opinion.
Upvotes: 1