2

I have two files f1.txt and f2.txt. I need to compare both files and print the matching coloums as well print the unmatched columns with "not found" pattern.

f1:

hari:1.2.3.4/32
abc:3.4.5.6/24
bcd:8.9.10.11/34

f2:

1.2.3.4/32
3.4.5.6/24
8.9.10.11/34
10.12.34.0/22
1.4.5.7/34

desired Output:

hari:1.2.3.4/32
abc:3.4.5.6/24
bcd:8.9.10.11/34
not found:10.12.34.0/22
not found:1.4.5.7/34

could anyone please help to get the desired output.

Thanks

2
  • So f1 contains lines of the pattern name:ip-slice and f2 contains lines only consisting of ip-slice. And the output shall be again a file like f1 but with all additional lines from f2 and the prefix not found: added?
    – Byte Commander
    Sep 6 '16 at 11:21
  • And can we assume that all ip slices in f1 are also in f2? Or what would the result need to be if not?
    – Byte Commander
    Sep 6 '16 at 11:31
4

You could use awk:

$ awk -F':' -vOFS=':' 'NR==FNR{a[$2]=$1;next}{print $1 in a?a[$1]:"not found",$1}' file1 file2
hari:1.2.3.4/32
abc:3.4.5.6/24
bcd:8.9.10.11/34
not found:10.12.34.0/22
not found:1.4.5.7/34

In a more readable format:

awk -F':' -vOFS=':' 'NR == FNR { # For the first file (file1)
                        a[$2] = $1 # store the first token in an array 
                                   # using the second token as the key
                        next       # skip to the next record
                     }
                     {  # For all lines of file 2
                        print $1 in a ? a[$1] : "not found" , $1 # print the desired result
                     }' file1 file2
1
  • 1
    @user2175455 If one of these answers solved your issue, please take a moment and accept it by clicking on the check mark to the left. That will mark the question as answered and is the way thanks are expressed on the Stack Exchange sites.
    – terdon
    Sep 6 '16 at 15:16
4

Although your f2 does not appear to be strictly ordered, join seems to work1:

$ join -t\: -12 -21 -a2 -e 'not found' -o1.1,0 f1 f2
hari:1.2.3.4/32
abc:3.4.5.6/24
bcd:8.9.10.11/34
not found:10.12.34.0/22
not found:1.4.5.7/34

With real data, you may need to pre-sort:

$ join -t\: -12 -21 -a2 -e 'not found' -o1.1,0 <(sort -t\: -k2,2 f1) <(sort -t\: -k1,1 f2) | sort
abc:3.4.5.6/24
bcd:8.9.10.11/34
hari:1.2.3.4/32
not found:10.12.34.0/22
not found:1.4.5.7/34


1 perhaps because the matchable lines are sorted?

2
  • +1 Nice answer, Why is the colon (:) escaped thought? On my system is seems to work even without the escape...
    – user000001
    Sep 6 '16 at 13:53
  • Good point - just habit I guess, : does have special meaning in bash (it's a no-op - you'll sometimes see it used as such e.g. : | paste - somefile or while : in place of while true) Sep 6 '16 at 14:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.