1

Is there an easy way to print all lines of a file1 (so that the output has the same number of lines as the input file1) but print a message such as NoMatch where the first entries of file1 does not match the first entries of file2?

file1:

Entry1 Entry2
a 2
b 3
c 4
d 5

file2:

a
b
b
a
d
d

Desired output:

Entry1
a 2
b 3
NoMatch 4
d 5

I am trying with

join -a1 -e "NoMatch" -11 -21 -o2.1 file1 file2

since I would like to keep the unpairable lines from file1 that do not match file2, and give a message for these cases as "no", but this keeps all of my records also in file2 (which contains duplicated records), what am I doing wrong? Could this be because my second file is tab delimited and my first file is space delimited?

Thanks so much for all the help...

6
  • Yes that is right... I have other columns that belong to file 1 though that identify the unmatched, let me make that clearer...
    – jamespower
    Commented Dec 4, 2015 at 3:34
  • Hmmm. Looks similar to unix.stackexchange.com/q/247223/139893. I wonder why? In that question, there was also a problem with a tab-delimited file.
    – RobertL
    Commented Dec 4, 2015 at 3:46
  • It is the same question made up of two, I will correct the other one sorry.
    – jamespower
    Commented Dec 4, 2015 at 4:13
  • Why use two different logins?
    – RobertL
    Commented Dec 4, 2015 at 9:02
  • 1
    You seem to have created two accounts. Please visit the contact form and select ‘I need to merge user profiles’. That way you'll be ab;e to respond to comments and properly manage all your posts.
    – terdon
    Commented Dec 4, 2015 at 9:27

1 Answer 1

2

With awk read file2 first and save $1 in seen[$1] then read file1 and if $1 wasn't "seen" replace it with NoMatch:

awk 'FNR==NR{seen[$1]++; next}
{(FNR==1 || ($1 in seen)) || $1="NoMatch"};1' file2 file1

If you prefer join, you need sorted input. You'll have to extract the header from file1 first, sort the remaining lines then join the result with the sorted file2:

{ head -n1; sort | join -j1 -a1 -e "NoMatch" -o 2.1 1.2 - <(sort file2); } <file1

and if needed, pipe everything to uniq to avoid duplicate lines:

{ head -n 1; sort | \
join -j1 -a1 -e "NoMatch" -o 2.1 1.2 - <(sort file2) | \
uniq; } <file1
5
  • Thanks so much don_crissti! Can I ask why I can't just ignore the header since it won't match to the other file anyway? I think I have been doing this wrong all along :/
    – jamespower
    Commented Dec 4, 2015 at 4:21
  • Thank you... I still can't get it to print my second value for the output, it prints "NoMatch" for the whole row...I don't understand why...
    – jamespower
    Commented Dec 4, 2015 at 4:39
  • I think I am using the brackets incorrectly, I get a syntax error... sorry I am a beginner... if I try this one step at a time and get the sortedFile1 without header and sortedFile2 without header in tab delimited format and then try this: { join -t $'\t' -a1 -e "NoMatch" -1 1 -2 1 -o 1.2,2.1 sortedFile2; } sortedFile1 )
    – jamespower
    Commented Dec 4, 2015 at 4:50
  • then it prints the whole line as "NoMatch" if it doesn't find it... there is no hope I will understand why tonight I guess, I will use the awk though at this point, thanks so much for all your help!
    – jamespower
    Commented Dec 4, 2015 at 5:03
  • I see what my issue is... I can get what I need from your awk command using paste with my file2... unix.stackexchange.com/questions/247223/…
    – jamespower
    Commented Dec 4, 2015 at 5:46

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .