I have two files:

File1         File2

abc           abc
cde           cde,xyz,efg,hij,...,n

efg           lmn,opq,weq,...n

Now I want to compare File1 line1 with File2 line1, line2 with line2 and so on. However, in File2 a single line can have multiple entries separated with 'comma'.

Now if the entry in File1 matches with any of the corresponding line entries in File2 the result should be OK, else show the difference.

For example:

File1         File2

cde           cde,xyz,efg,hij,opt

the result should be OK because cde exist in both files.

Can you please help me out to write a shell script like diff gave me, including the entry differences.

closed as unclear what you're asking by jasonwryan, Anthon, Networker, jimmij, peterph Jan 14 '15 at 10:22

Please clarify your specific problem or add additional details to highlight exactly what you need. As it's currently written, it’s hard to tell exactly what you're asking. See the How to Ask page for help clarifying this question. If this question can be reworded to fit the rules in the help center, please edit the question.

  • Does file1 always only have one field? – Runium Jan 14 '15 at 7:13
  • No effort from the OP, just asking for complete solution. – peterph Jan 14 '15 at 10:22

Not very pretty perhaps but something like this could be a start:

# 1. Read lines from file1 as string, and file2 as comma-separated array.
while read -r a && IFS=, read -ra b <&3; do
    # 2. If both empty lines, continue.
    if [[ "$a" == "" && ${#b[@]} == 0 ]]; then
    # 3. Start assuming diff.
    # 4. Loop fields in $b.
    for e in ${b[@]}; do
        # Compare field in $b with $a, if match then abort.
        if [[ "$e" == "$a" ]]; then
    # 5. If no match found, print line from $b.
    if [[ $diff == 1 ]]; then
        # Join array with <space>comma.
        line=$(printf ", %s" "${b[@]}")
        # Print line, excluding leading <space>comma.
        printf "%s\n" "${line:2}"
# Input argument one as file 1 to stdin, and argument two as file 2 to
# file descriptor 3.
done < "$1" 3<"$2"

Typically used as:

$ ./myscript file1 file2

Now using something like Python, Perl, awk etc. or would likely be better.

  • Thank you. But there is a problem for the same. if 1 file has efg and other has efghi,abc,def... it gives a exact match.. How can i check that – Karan Kohli Jan 14 '15 at 9:15
  • @KaranKohli: Do I read you correctly if you are saying you want file1:efg to match file2:efghi ? – user367890 Jan 14 '15 at 9:19
  • @KaranKohli: And, if so, do you also want file1:efghi to match file2:efg? And what about sub-matches? Should file1:efg and file2:xxefgxx or file1:efg and file2:xxefg also result in OK (skip/no diff)? – user367890 Jan 14 '15 at 9:25
  • @KaranKohli: You are welcome :) – user367890 Jan 14 '15 at 9:29

Maybe this stack overflow answers put you in the right direction:

  1. Looping through the content of a file in Bash?
  2. String contains in bash

Most probably you want to put each line of each file in a loop list or array, using the first suggestion. Then iterate over both of them simultaneous and compare the strings using the second suggestion.

  • Thanks Tim. However, I already tried the above 2 links. I always get stuck in comparing the exact lines if in multiple loop – Karan Kohli Jan 14 '15 at 7:21

Here is a one liner:

If it finds what you are looking for, it displays "OK".

If it doesn't, it displays the word it searched for.

for i in $(cat File1); do grep -q $i File2 && echo OK || echo $i; done


paste file1 file2 | grep -vP '^(.*)\t.*\1.*'

and possibly adapt the regex to your case.


With GNU awk you can do it in one line:

awk '{a=$0;getline <File2;if($0 ~ a)print "OK"; else print a,$0}' File1

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