Neel
Neel

Reputation: 1

Compare columns between 2 files using TCL

I have 2 files having only one column. Say file1.txt and file2.txt. Below are the contents inside the file Inside file1.txt

Tom
Harry
Snowy
Edward

Inside file2.txt

Harry
Tom
Edward

2) I want to write a code that will check each item in the column and print something as below.

"Tom, Harry, Edward" are present in both the files
Snowy is there in file1.txt but not in file2.txt

3) Basic code

    set a [open file1.txt r]
set b [open file2.txt r]
while {[gets $a line1] >= 0 && [gets $b line2] >= 0} {
    foreach a_line $line1 {
        foreach b_line $line2 {
            if {$a_line == $b_line } {
            puts "$a_line in file test1 is present in $b_line in file test2\n"
            } else {
            puts "$a_line is not there\n"
            }
        }
    }
}
close $a
close $b

Issue is that it is not checking each name in the column. Any suggestions.

Thanks in advance. Neel

Upvotes: 0

Views: 830

Answers (1)

glenn jackman
glenn jackman

Reputation: 247240

What you want to do is read each file separately and not have nested loops:

# read the contents of file1 into an associative array
# store the user as an array **key** for fast lookoup
set fh [open "file1.txt" r]
while {[gets $fh user] != -1} {
    set f1tmp($user) ""
}
close $fh

# read file2 and compare against file1
array set users {both {} file1 {} file2 {}}
set fh [open "file2.txt" r]
while {[gets $fh user] != -1} {
    if {[info exists f1tmp($user)]} {
        lappend users(both) $user
        unset f1tmp($user)
    } else {
        lappend users(file2) $user
    }
}
close $fh

set users(file1) [array names f1tmp]
parray users
users(both)  = Harry Tom Edward
users(file1) = Snowy
users(file2) = 

Or as Donal suggests, use tcllib

package require struct::set

set fh [open file1.txt r]
set f1users [split [read -nonewline $fh] \n]
close $fh

set fh [open file2.txt r]
set f2users [split [read -nonewline $fh] \n]
close $fh

set results [struct::set intersect3 $f1users $f2users]
puts "in both: [join [lindex $results 0] ,]"
puts "f1 only: [join [lindex $results 1] ,]"
puts "f2 only: [join [lindex $results 2] ,]"
in both: Harry,Tom,Edward
f1 only: Snowy
f2 only:

Upvotes: 1

Related Questions