Compare first column of one file with the first column of second and print associated column of each if there was a match










3














I have two files, I need to compare their first columns and if the match is found, I'd like to output the corresponding values from both files.



Similar to this Q but I'd like to print columns from both files not one: How to compare multiple columns in two files and retrieve the corresponding value from another column if match found



File1.txt



adeqY 33.7
AIsLX 65.6
AmuBv 1589.0
aZMIx 84.4


File2.txt



AmuBv foo
iwwlp bar
adeqY hi
qUbJZ bye


Output



hi 33.7
foo 1589.0


I have the following awk command but I only managed to print the second column match from File2:



awk 'FNR==NRa[$1]; next ($1) in a print $2 a[$2]' File1.txt File2.txt



a[$2] doesn't want to print



Thanks in advance.










share|improve this question























  • By seeing your profile @eskp, got to know you never select any answer as correct answer. Give it sometime let answers come for your question and then you could select anyone of the answer as correct answer out of all, see this link too once stackoverflow.com/help/someone-answers
    – RavinderSingh13
    Nov 13 '18 at 3:03















3














I have two files, I need to compare their first columns and if the match is found, I'd like to output the corresponding values from both files.



Similar to this Q but I'd like to print columns from both files not one: How to compare multiple columns in two files and retrieve the corresponding value from another column if match found



File1.txt



adeqY 33.7
AIsLX 65.6
AmuBv 1589.0
aZMIx 84.4


File2.txt



AmuBv foo
iwwlp bar
adeqY hi
qUbJZ bye


Output



hi 33.7
foo 1589.0


I have the following awk command but I only managed to print the second column match from File2:



awk 'FNR==NRa[$1]; next ($1) in a print $2 a[$2]' File1.txt File2.txt



a[$2] doesn't want to print



Thanks in advance.










share|improve this question























  • By seeing your profile @eskp, got to know you never select any answer as correct answer. Give it sometime let answers come for your question and then you could select anyone of the answer as correct answer out of all, see this link too once stackoverflow.com/help/someone-answers
    – RavinderSingh13
    Nov 13 '18 at 3:03













3












3








3


1





I have two files, I need to compare their first columns and if the match is found, I'd like to output the corresponding values from both files.



Similar to this Q but I'd like to print columns from both files not one: How to compare multiple columns in two files and retrieve the corresponding value from another column if match found



File1.txt



adeqY 33.7
AIsLX 65.6
AmuBv 1589.0
aZMIx 84.4


File2.txt



AmuBv foo
iwwlp bar
adeqY hi
qUbJZ bye


Output



hi 33.7
foo 1589.0


I have the following awk command but I only managed to print the second column match from File2:



awk 'FNR==NRa[$1]; next ($1) in a print $2 a[$2]' File1.txt File2.txt



a[$2] doesn't want to print



Thanks in advance.










share|improve this question















I have two files, I need to compare their first columns and if the match is found, I'd like to output the corresponding values from both files.



Similar to this Q but I'd like to print columns from both files not one: How to compare multiple columns in two files and retrieve the corresponding value from another column if match found



File1.txt



adeqY 33.7
AIsLX 65.6
AmuBv 1589.0
aZMIx 84.4


File2.txt



AmuBv foo
iwwlp bar
adeqY hi
qUbJZ bye


Output



hi 33.7
foo 1589.0


I have the following awk command but I only managed to print the second column match from File2:



awk 'FNR==NRa[$1]; next ($1) in a print $2 a[$2]' File1.txt File2.txt



a[$2] doesn't want to print



Thanks in advance.







bash awk sysadmin






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 13 '18 at 2:57









RavinderSingh13

25.8k41438




25.8k41438










asked Nov 13 '18 at 2:04









eskpeskp

5315




5315











  • By seeing your profile @eskp, got to know you never select any answer as correct answer. Give it sometime let answers come for your question and then you could select anyone of the answer as correct answer out of all, see this link too once stackoverflow.com/help/someone-answers
    – RavinderSingh13
    Nov 13 '18 at 3:03
















  • By seeing your profile @eskp, got to know you never select any answer as correct answer. Give it sometime let answers come for your question and then you could select anyone of the answer as correct answer out of all, see this link too once stackoverflow.com/help/someone-answers
    – RavinderSingh13
    Nov 13 '18 at 3:03















By seeing your profile @eskp, got to know you never select any answer as correct answer. Give it sometime let answers come for your question and then you could select anyone of the answer as correct answer out of all, see this link too once stackoverflow.com/help/someone-answers
– RavinderSingh13
Nov 13 '18 at 3:03




By seeing your profile @eskp, got to know you never select any answer as correct answer. Give it sometime let answers come for your question and then you could select anyone of the answer as correct answer out of all, see this link too once stackoverflow.com/help/someone-answers
– RavinderSingh13
Nov 13 '18 at 3:03












4 Answers
4






active

oldest

votes


















1














Could you please try following.



awk 'FNR==NRa[$1]=$2;next ($1 in a)print $2,a[$1]' Input_file1 Input_file2


Output will be as follows.



foo 1589.0
hi 33.7


Problem in your attempt: You was going good only thing in FNR==NR condition your a[$1] is NOT having any value it only created its index in array a so that is why it was not able to print anything when 2nd Input_file is being read.






share|improve this answer




























    1














    What you are trying to do there is essentially an INNER JOIN on two tables stored in text files and the Linux join command is designed for just that.



    Try:



    join -t' ' -1 1 -2 1 -o 2.2,1.2 <(sort file1.txt) <(sort file2.txt) 
    foo 1589.0
    hi 33.7


    Explanation:



    • The field separator is specified as -t. I assumed that your data is separated by a single space in these text files.

    • The -1 1 -2 1 is says to join on the first field for the left-hand side file and the first field on the right-hand side file.

    • The -o 2.2,1.2 defines the fields you want to return. The second field from the second file then the second field from the first file.

    • Finally, note that I sorted the input files as the files need to be sorted by the field that you intend to join by for the Linux join to work.

    See also this blog (ref).






    share|improve this answer




























      0














      What's happening here is that, once you're printing results in the last awk statement, the a array is no longer in scope, hence why that second value is not printing.



      Maybe there is another way to do this awk, but this is the solution I came up with:



      for each in $(comm -1 -2 <(awk 'print $1 ' file1.txt | sort ) <(awk 'print $1 ' file2.txt | sort) ); do echo $(grep $each file2.txt | awk 'print $2') $(grep $each file1.txt | awk 'print $2') ; done;


      This outputs:



      foo 1589.0
      hi 33.7


      Explanation:



      • Run a comm command on the two files.

      • The two "files" given to comm are actually process substituted, so that they are sorted first (comm expects sorted input) and only the first column is shown.

      • The -1 -2 parameters to comm tells it to only print the common elements from the files (it can show elements unique to first file, unique to second file, or common to both)

      • Once you have the common elements from both files, for each of those common elements, go ahead and grep each of the files for the line where it appears, and show only the second value, using awk.

      So, in the end, we needed a bash for loop, sort, comm and awk multiple times. Not the most elegant solution probably, but it gets the job done.






      share|improve this answer






























        0














        Try Perl variant



        $ cat eskp1.txt
        adeqY 33.7
        AIsLX 65.6
        AmuBv 1589.0
        aZMIx 84.4

        $ cat eskp2.txt
        AmuBv foo
        iwwlp bar
        adeqY hi
        qUbJZ bye

        $ perl -F"s+" -lane 'BEGIN %kv=mapsplit /s+/ qx(cat eskp1.txt) print "$F[1] $kv$F[0]" if $kv$F[0] ' eskp2.txt
        foo 1589.0
        hi 33.7





        share|improve this answer




















          Your Answer






          StackExchange.ifUsing("editor", function ()
          StackExchange.using("externalEditor", function ()
          StackExchange.using("snippets", function ()
          StackExchange.snippets.init();
          );
          );
          , "code-snippets");

          StackExchange.ready(function()
          var channelOptions =
          tags: "".split(" "),
          id: "1"
          ;
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function()
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled)
          StackExchange.using("snippets", function()
          createEditor();
          );

          else
          createEditor();

          );

          function createEditor()
          StackExchange.prepareEditor(
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader:
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          ,
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          );



          );













          draft saved

          draft discarded


















          StackExchange.ready(
          function ()
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53272722%2fcompare-first-column-of-one-file-with-the-first-column-of-second-and-print-assoc%23new-answer', 'question_page');

          );

          Post as a guest















          Required, but never shown

























          4 Answers
          4






          active

          oldest

          votes








          4 Answers
          4






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          1














          Could you please try following.



          awk 'FNR==NRa[$1]=$2;next ($1 in a)print $2,a[$1]' Input_file1 Input_file2


          Output will be as follows.



          foo 1589.0
          hi 33.7


          Problem in your attempt: You was going good only thing in FNR==NR condition your a[$1] is NOT having any value it only created its index in array a so that is why it was not able to print anything when 2nd Input_file is being read.






          share|improve this answer

























            1














            Could you please try following.



            awk 'FNR==NRa[$1]=$2;next ($1 in a)print $2,a[$1]' Input_file1 Input_file2


            Output will be as follows.



            foo 1589.0
            hi 33.7


            Problem in your attempt: You was going good only thing in FNR==NR condition your a[$1] is NOT having any value it only created its index in array a so that is why it was not able to print anything when 2nd Input_file is being read.






            share|improve this answer























              1












              1








              1






              Could you please try following.



              awk 'FNR==NRa[$1]=$2;next ($1 in a)print $2,a[$1]' Input_file1 Input_file2


              Output will be as follows.



              foo 1589.0
              hi 33.7


              Problem in your attempt: You was going good only thing in FNR==NR condition your a[$1] is NOT having any value it only created its index in array a so that is why it was not able to print anything when 2nd Input_file is being read.






              share|improve this answer












              Could you please try following.



              awk 'FNR==NRa[$1]=$2;next ($1 in a)print $2,a[$1]' Input_file1 Input_file2


              Output will be as follows.



              foo 1589.0
              hi 33.7


              Problem in your attempt: You was going good only thing in FNR==NR condition your a[$1] is NOT having any value it only created its index in array a so that is why it was not able to print anything when 2nd Input_file is being read.







              share|improve this answer












              share|improve this answer



              share|improve this answer










              answered Nov 13 '18 at 2:57









              RavinderSingh13RavinderSingh13

              25.8k41438




              25.8k41438























                  1














                  What you are trying to do there is essentially an INNER JOIN on two tables stored in text files and the Linux join command is designed for just that.



                  Try:



                  join -t' ' -1 1 -2 1 -o 2.2,1.2 <(sort file1.txt) <(sort file2.txt) 
                  foo 1589.0
                  hi 33.7


                  Explanation:



                  • The field separator is specified as -t. I assumed that your data is separated by a single space in these text files.

                  • The -1 1 -2 1 is says to join on the first field for the left-hand side file and the first field on the right-hand side file.

                  • The -o 2.2,1.2 defines the fields you want to return. The second field from the second file then the second field from the first file.

                  • Finally, note that I sorted the input files as the files need to be sorted by the field that you intend to join by for the Linux join to work.

                  See also this blog (ref).






                  share|improve this answer

























                    1














                    What you are trying to do there is essentially an INNER JOIN on two tables stored in text files and the Linux join command is designed for just that.



                    Try:



                    join -t' ' -1 1 -2 1 -o 2.2,1.2 <(sort file1.txt) <(sort file2.txt) 
                    foo 1589.0
                    hi 33.7


                    Explanation:



                    • The field separator is specified as -t. I assumed that your data is separated by a single space in these text files.

                    • The -1 1 -2 1 is says to join on the first field for the left-hand side file and the first field on the right-hand side file.

                    • The -o 2.2,1.2 defines the fields you want to return. The second field from the second file then the second field from the first file.

                    • Finally, note that I sorted the input files as the files need to be sorted by the field that you intend to join by for the Linux join to work.

                    See also this blog (ref).






                    share|improve this answer























                      1












                      1








                      1






                      What you are trying to do there is essentially an INNER JOIN on two tables stored in text files and the Linux join command is designed for just that.



                      Try:



                      join -t' ' -1 1 -2 1 -o 2.2,1.2 <(sort file1.txt) <(sort file2.txt) 
                      foo 1589.0
                      hi 33.7


                      Explanation:



                      • The field separator is specified as -t. I assumed that your data is separated by a single space in these text files.

                      • The -1 1 -2 1 is says to join on the first field for the left-hand side file and the first field on the right-hand side file.

                      • The -o 2.2,1.2 defines the fields you want to return. The second field from the second file then the second field from the first file.

                      • Finally, note that I sorted the input files as the files need to be sorted by the field that you intend to join by for the Linux join to work.

                      See also this blog (ref).






                      share|improve this answer












                      What you are trying to do there is essentially an INNER JOIN on two tables stored in text files and the Linux join command is designed for just that.



                      Try:



                      join -t' ' -1 1 -2 1 -o 2.2,1.2 <(sort file1.txt) <(sort file2.txt) 
                      foo 1589.0
                      hi 33.7


                      Explanation:



                      • The field separator is specified as -t. I assumed that your data is separated by a single space in these text files.

                      • The -1 1 -2 1 is says to join on the first field for the left-hand side file and the first field on the right-hand side file.

                      • The -o 2.2,1.2 defines the fields you want to return. The second field from the second file then the second field from the first file.

                      • Finally, note that I sorted the input files as the files need to be sorted by the field that you intend to join by for the Linux join to work.

                      See also this blog (ref).







                      share|improve this answer












                      share|improve this answer



                      share|improve this answer










                      answered Nov 13 '18 at 3:17









                      Alex HarveyAlex Harvey

                      3,8971823




                      3,8971823





















                          0














                          What's happening here is that, once you're printing results in the last awk statement, the a array is no longer in scope, hence why that second value is not printing.



                          Maybe there is another way to do this awk, but this is the solution I came up with:



                          for each in $(comm -1 -2 <(awk 'print $1 ' file1.txt | sort ) <(awk 'print $1 ' file2.txt | sort) ); do echo $(grep $each file2.txt | awk 'print $2') $(grep $each file1.txt | awk 'print $2') ; done;


                          This outputs:



                          foo 1589.0
                          hi 33.7


                          Explanation:



                          • Run a comm command on the two files.

                          • The two "files" given to comm are actually process substituted, so that they are sorted first (comm expects sorted input) and only the first column is shown.

                          • The -1 -2 parameters to comm tells it to only print the common elements from the files (it can show elements unique to first file, unique to second file, or common to both)

                          • Once you have the common elements from both files, for each of those common elements, go ahead and grep each of the files for the line where it appears, and show only the second value, using awk.

                          So, in the end, we needed a bash for loop, sort, comm and awk multiple times. Not the most elegant solution probably, but it gets the job done.






                          share|improve this answer



























                            0














                            What's happening here is that, once you're printing results in the last awk statement, the a array is no longer in scope, hence why that second value is not printing.



                            Maybe there is another way to do this awk, but this is the solution I came up with:



                            for each in $(comm -1 -2 <(awk 'print $1 ' file1.txt | sort ) <(awk 'print $1 ' file2.txt | sort) ); do echo $(grep $each file2.txt | awk 'print $2') $(grep $each file1.txt | awk 'print $2') ; done;


                            This outputs:



                            foo 1589.0
                            hi 33.7


                            Explanation:



                            • Run a comm command on the two files.

                            • The two "files" given to comm are actually process substituted, so that they are sorted first (comm expects sorted input) and only the first column is shown.

                            • The -1 -2 parameters to comm tells it to only print the common elements from the files (it can show elements unique to first file, unique to second file, or common to both)

                            • Once you have the common elements from both files, for each of those common elements, go ahead and grep each of the files for the line where it appears, and show only the second value, using awk.

                            So, in the end, we needed a bash for loop, sort, comm and awk multiple times. Not the most elegant solution probably, but it gets the job done.






                            share|improve this answer

























                              0












                              0








                              0






                              What's happening here is that, once you're printing results in the last awk statement, the a array is no longer in scope, hence why that second value is not printing.



                              Maybe there is another way to do this awk, but this is the solution I came up with:



                              for each in $(comm -1 -2 <(awk 'print $1 ' file1.txt | sort ) <(awk 'print $1 ' file2.txt | sort) ); do echo $(grep $each file2.txt | awk 'print $2') $(grep $each file1.txt | awk 'print $2') ; done;


                              This outputs:



                              foo 1589.0
                              hi 33.7


                              Explanation:



                              • Run a comm command on the two files.

                              • The two "files" given to comm are actually process substituted, so that they are sorted first (comm expects sorted input) and only the first column is shown.

                              • The -1 -2 parameters to comm tells it to only print the common elements from the files (it can show elements unique to first file, unique to second file, or common to both)

                              • Once you have the common elements from both files, for each of those common elements, go ahead and grep each of the files for the line where it appears, and show only the second value, using awk.

                              So, in the end, we needed a bash for loop, sort, comm and awk multiple times. Not the most elegant solution probably, but it gets the job done.






                              share|improve this answer














                              What's happening here is that, once you're printing results in the last awk statement, the a array is no longer in scope, hence why that second value is not printing.



                              Maybe there is another way to do this awk, but this is the solution I came up with:



                              for each in $(comm -1 -2 <(awk 'print $1 ' file1.txt | sort ) <(awk 'print $1 ' file2.txt | sort) ); do echo $(grep $each file2.txt | awk 'print $2') $(grep $each file1.txt | awk 'print $2') ; done;


                              This outputs:



                              foo 1589.0
                              hi 33.7


                              Explanation:



                              • Run a comm command on the two files.

                              • The two "files" given to comm are actually process substituted, so that they are sorted first (comm expects sorted input) and only the first column is shown.

                              • The -1 -2 parameters to comm tells it to only print the common elements from the files (it can show elements unique to first file, unique to second file, or common to both)

                              • Once you have the common elements from both files, for each of those common elements, go ahead and grep each of the files for the line where it appears, and show only the second value, using awk.

                              So, in the end, we needed a bash for loop, sort, comm and awk multiple times. Not the most elegant solution probably, but it gets the job done.







                              share|improve this answer














                              share|improve this answer



                              share|improve this answer








                              edited Nov 13 '18 at 3:05

























                              answered Nov 13 '18 at 2:57









                              mjuarezmjuarez

                              9,76973751




                              9,76973751





















                                  0














                                  Try Perl variant



                                  $ cat eskp1.txt
                                  adeqY 33.7
                                  AIsLX 65.6
                                  AmuBv 1589.0
                                  aZMIx 84.4

                                  $ cat eskp2.txt
                                  AmuBv foo
                                  iwwlp bar
                                  adeqY hi
                                  qUbJZ bye

                                  $ perl -F"s+" -lane 'BEGIN %kv=mapsplit /s+/ qx(cat eskp1.txt) print "$F[1] $kv$F[0]" if $kv$F[0] ' eskp2.txt
                                  foo 1589.0
                                  hi 33.7





                                  share|improve this answer

























                                    0














                                    Try Perl variant



                                    $ cat eskp1.txt
                                    adeqY 33.7
                                    AIsLX 65.6
                                    AmuBv 1589.0
                                    aZMIx 84.4

                                    $ cat eskp2.txt
                                    AmuBv foo
                                    iwwlp bar
                                    adeqY hi
                                    qUbJZ bye

                                    $ perl -F"s+" -lane 'BEGIN %kv=mapsplit /s+/ qx(cat eskp1.txt) print "$F[1] $kv$F[0]" if $kv$F[0] ' eskp2.txt
                                    foo 1589.0
                                    hi 33.7





                                    share|improve this answer























                                      0












                                      0








                                      0






                                      Try Perl variant



                                      $ cat eskp1.txt
                                      adeqY 33.7
                                      AIsLX 65.6
                                      AmuBv 1589.0
                                      aZMIx 84.4

                                      $ cat eskp2.txt
                                      AmuBv foo
                                      iwwlp bar
                                      adeqY hi
                                      qUbJZ bye

                                      $ perl -F"s+" -lane 'BEGIN %kv=mapsplit /s+/ qx(cat eskp1.txt) print "$F[1] $kv$F[0]" if $kv$F[0] ' eskp2.txt
                                      foo 1589.0
                                      hi 33.7





                                      share|improve this answer












                                      Try Perl variant



                                      $ cat eskp1.txt
                                      adeqY 33.7
                                      AIsLX 65.6
                                      AmuBv 1589.0
                                      aZMIx 84.4

                                      $ cat eskp2.txt
                                      AmuBv foo
                                      iwwlp bar
                                      adeqY hi
                                      qUbJZ bye

                                      $ perl -F"s+" -lane 'BEGIN %kv=mapsplit /s+/ qx(cat eskp1.txt) print "$F[1] $kv$F[0]" if $kv$F[0] ' eskp2.txt
                                      foo 1589.0
                                      hi 33.7






                                      share|improve this answer












                                      share|improve this answer



                                      share|improve this answer










                                      answered Nov 14 '18 at 6:40









                                      stack0114106stack0114106

                                      2,3411417




                                      2,3411417



























                                          draft saved

                                          draft discarded
















































                                          Thanks for contributing an answer to Stack Overflow!


                                          • Please be sure to answer the question. Provide details and share your research!

                                          But avoid


                                          • Asking for help, clarification, or responding to other answers.

                                          • Making statements based on opinion; back them up with references or personal experience.

                                          To learn more, see our tips on writing great answers.





                                          Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                                          Please pay close attention to the following guidance:


                                          • Please be sure to answer the question. Provide details and share your research!

                                          But avoid


                                          • Asking for help, clarification, or responding to other answers.

                                          • Making statements based on opinion; back them up with references or personal experience.

                                          To learn more, see our tips on writing great answers.




                                          draft saved


                                          draft discarded














                                          StackExchange.ready(
                                          function ()
                                          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53272722%2fcompare-first-column-of-one-file-with-the-first-column-of-second-and-print-assoc%23new-answer', 'question_page');

                                          );

                                          Post as a guest















                                          Required, but never shown





















































                                          Required, but never shown














                                          Required, but never shown












                                          Required, but never shown







                                          Required, but never shown

































                                          Required, but never shown














                                          Required, but never shown












                                          Required, but never shown







                                          Required, but never shown







                                          這個網誌中的熱門文章

                                          How to read a connectionString WITH PROVIDER in .NET Core?

                                          In R, how to develop a multiplot heatmap.2 figure showing key labels successfully

                                          Museum of Modern and Contemporary Art of Trento and Rovereto