0

I have two files

file1:

45 789 
46 4546
78 4564
71 546

file2:

41 456 
46 456
40 465
45 456

I would like to compare these files and get an output: if the number in first column from first file is in the first column of the second file print a row from second file that include this number.

Desired output:

46 456
45 456

It will be something with grep? Thank you very much

3 Answers 3

3

Read the first file's column to populate an array of "seen" values. Then when reading the second file, if the first value has been "seen", print the record:

$ awk 'NR == FNR { data[$1] = 1 } NR != FNR && data[$1] { print }' file1 file2
46 456
45 456

Rather than using the FR == NR and FR != NR tests, we could also use FILENAME == "file1" and FILENAME == "file2".

2
  • Thank you very much and what is the difference of these solutions? Apr 23, 2019 at 19:53
  • The difference is that the solution given will work on any number of subsequent files beyond the first two; hard-coding the file names will only work on two files with the specific names given. Comparing NR and FNR is a simple "is this the first file or literally any other file" test.
    – DopeGhoti
    Apr 23, 2019 at 19:56
2

Assuming your shell is bash/ksh/zsh:

join -o 0,2.2 <(sort file1) <(sort file2)
0
1

command

awk 'NR==FNR{a[$1];next}($1 in a){print $0}' file1 file2

output

46 456
45 456
4
  • This code-only answer would be much improved if you explained what and how the awk code is doing. Apr 24, 2019 at 10:53
  • This works much like the currently accepted answer; the main difference is that it "short circuits" after filling the "seen values" array rather than testing for inequality of NR and FNR.
    – DopeGhoti
    Apr 24, 2019 at 16:05
  • @DopeGhoti can you explain the awk command in detail … what is actually doing .. and how the file2 is processed in above command Feb 4, 2021 at 5:46
  • The awk code has two blocks; one which runs only on the first file (when FNR==NR, which is to say the record number from the file is equal to the overall record number -- which is only the case for the first file) adds the first value of the record to an array, a, and then moves on to the next record without further processing. The second block (which only runs on files other than the first) looks to see if the first value is in the array a and if so, prints the entire record.
    – DopeGhoti
    Feb 4, 2021 at 7:10

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.