Brajesh
Brajesh

Reputation: 351

Print the input search string if grep doesn't match

I have file1

BOB
JOHN
SALLY

I have file2

There was a boy called JOHN and he was playing with FRED while
JILL went off to find a bucket of water from TOM but she
fell down the hill.

I want to iterate through the file1 words and search for these in file2.
I want to print the words that are NOT found in file2.

So the output would be

BOB
SALLY

I guess it is if the grep fails, I'd like to print the string that grep was searching for.

I'm starting here:

grep -o -f file1 file2 

But of course, this returns

JOHN

How would I get the original search strings that didn't match - to print instead?

Upvotes: 3

Views: 237

Answers (3)

anubhava
anubhava

Reputation: 785058

Here is a grep one liner to get this done:

grep -vxFf <(tr '[[:blank:]]' '\n' < file2) file1

BOB
SALLY

Using tr to convert space/tab to newline first then using grep -vxFf to get non-matching words in file1.

Or as David suggested in comments below:

grep -vxFf <(printf '%s\n' $(<file2)) file1

Upvotes: 7

RavinderSingh13
RavinderSingh13

Reputation: 133458

With your shown samples could you please try following.

awk '
FNR==NR{
  arr[$0]
  next
}
{
  for(i in arr){
    if(index($0,i)){
      delete arr[i]
      next
    }
  }
}
END{
  for(i in arr){
    print i
  }
}
' file1 file2

Upvotes: 5

David C. Rankin
David C. Rankin

Reputation: 84551

If the order isn't critical, you can use:

awk '
    FNR == NR { a[$1]=0; next } 
    { for (i=1;i<=NF;i++)
        if ($i in a)
            a[$i]++
    }
    END { 
        for (i in a)
            if (!a[i])
                print i 
    }
' file1 file2

Example Use/Output

$ awk '
>     FNR == NR { a[$1]=0; next }
>     { for (i=1;i<=NF;i++)
>         if ($i in a)
>             a[$i]++
>     }
>     END {
>         for (i in a)
>             if (!a[i])
>                 print i
>     }
> ' file1 file2
SALLY
BOB

Upvotes: 3

Related Questions