Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TCL - find a regular pattern in a file and return the occurrence and number of occurrences

Tags:

tcl

I am writing a code to grep a regular expression pattern from a file, and output that regular expression and the number of times it has occured.

Here is the code: I am trying to find the pattern "grep" in my file hello.txt:

set file1 [open "hello.txt" r]
set file2 [read $file1]
regexp {grep} $file2 matched
puts $matched
while {[eof $file2] != 1} {
set number 0
if {[regexp {grep} $file2 matched] >= 0} {
 incr number
}

puts $number
}

Output that I got:

grep

--------
can not find channel named "qwerty
iiiiiii
wxseddtt
lsakdfhaiowehf'
jbsdcfiweg
kajsbndimm s
grep
afnQWFH
 ACV;SKDJNCV;
    qw  qde 
 kI UQWG
grep
grep"
    while executing
"eof $file2"
like image 773
prashanthi Avatar asked Dec 17 '22 12:12

prashanthi


2 Answers

It's usually a mistake to check for eof in a while loop -- check the return code from gets instead:

set filename "hello.txt"
set pattern {grep}
set count 0

set fid [open $filename r]
while {[gets $fid line] != -1} {
    incr count [regexp -all -- $pattern $line]
}
close $fid

puts "$count occurrances of $pattern in $filename"

Another thought: if you're just counting pattern matches, assuming your file is not too large:

set fid [open $filename r]
set count [regexp -all -- $pattern [read $fid [file size $filename]]]
close $fid
like image 160
glenn jackman Avatar answered May 05 '23 08:05

glenn jackman


The error message is caused by the command eof $file2. The reason is that $file2 is not a file handle (resp. channel) but contains the content of the file hello.txt itself. You read this file content with set file2 [read $file1].

If you want to do it like that I would suggest to rename $file2 into something like $filecontent and loop over every contained line:

foreach line [split $filecontent "\n"] {
  ... do something ...
}
like image 22
bmk Avatar answered May 05 '23 09:05

bmk