2

I have a file (file 1) which reads something like this:

2  test1
3  test2 
2  test3 
1  test1 
4  test2

And there is a master file (file2):

2    test1
3  test1
4         test1
2  test2
3 test2
4   test2
5 test2 
...

I want to print all the lines from file2 when there is match between column 1 and column 2 from file 1. I want to keep the random formatting of file 2 preserved. What would be the best way to do this?

7

try

awk 'NR==FNR { a[$1 $2]=1 ; } NR>FNR { if ( $1 $2 in a ) print ;}'

where

  • NR==FNR Number of Record == File Number of Record (we are in first file)
  • { a[$1 $2]=1 ; } store key (concatenation without space)
  • NR>FNR (we are in second file)
  • if ( $1 $2 in a ) if index in present ...
  • print print the line.

which give for you sample

2    test1
3 test2
4   test2
  • 3
    can be simplified to awk 'NR==FNR { a[$1 $2] ; next} ( $1 $2 in a )' – Sundeep Mar 23 '17 at 15:25
  • 1
    I didn't think of it, however I tried to use explicit code, which is easiest to explain. after poster get familiar with awk, he can procced with golfing code. – Archemar Mar 23 '17 at 15:43
  • 1
    It would be better to apply something like a[$1"-"$2] since with plain a[$1 $2] , possible records 1 1test and 11 test will be treated as the same thing due to awk concatenation. – George Vasiliou Mar 23 '17 at 20:10
5
awk 'n[$1][$2]++'   file1 file2

Assuming no duplicates in either files.

  • 3
    Minor nit: this breaks if there are duplicate lines in file1. A possible fix: awk 'n[$1][$2]++ && NR!=FNR' file1 file2. – Satō Katsura Mar 23 '17 at 15:25
  • 1
    Actually, strike that. It also breaks if there are duplicate lines in file2. – Satō Katsura Mar 23 '17 at 15:30
  • 1
    Thanks JJoao and Sato ! It works. Fortunately, there are no duplicates in either files :-) – Ash Mar 23 '17 at 15:36
  • 1
    @GeorgeVasiliou, True, thank you, (I upvoted Archemar solution). We are pointing basic directions. With Gigabytes everything has to be reviewed. I used bi-dimensional arrays because "2 4test" and "24 test" would be equal in Archemars's solution (there is other ways to avoid this minor issue) – JJoao Mar 23 '17 at 15:57
  • 1
    By the way In the well known SO "grep benchmark" both awk solutions worked ok and with similar timing results tested with some huge files that were built by fellows over there :-) – George Vasiliou Mar 23 '17 at 16:03
0
perl -lane '@ARGV and $h{"@F"}++,next; print if $h{"@F"}' file1 file2

Output

2    test1
3 test2
4   test2

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.