Using awk to sum the values of a column, based on the values of another column

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
48
down vote

favorite
16












I am trying to sum certain numbers in a column using awk. I would like to sum just column 3 of the "smiths" to get a total of 212. I can sum the whole column using awk but not just the "smiths". I have:



awk 'BEGIN FS = " ; sum+=$3 END print sum' filename.txt


Also I am using putty. Thank you for any help.



smiths|Login|2
olivert|Login|10
denniss|Payroll|100
smiths|Time|200
smiths|Logout|10









share|improve this question



























    up vote
    48
    down vote

    favorite
    16












    I am trying to sum certain numbers in a column using awk. I would like to sum just column 3 of the "smiths" to get a total of 212. I can sum the whole column using awk but not just the "smiths". I have:



    awk 'BEGIN FS = " ; sum+=$3 END print sum' filename.txt


    Also I am using putty. Thank you for any help.



    smiths|Login|2
    olivert|Login|10
    denniss|Payroll|100
    smiths|Time|200
    smiths|Logout|10









    share|improve this question

























      up vote
      48
      down vote

      favorite
      16









      up vote
      48
      down vote

      favorite
      16






      16





      I am trying to sum certain numbers in a column using awk. I would like to sum just column 3 of the "smiths" to get a total of 212. I can sum the whole column using awk but not just the "smiths". I have:



      awk 'BEGIN FS = " ; sum+=$3 END print sum' filename.txt


      Also I am using putty. Thank you for any help.



      smiths|Login|2
      olivert|Login|10
      denniss|Payroll|100
      smiths|Time|200
      smiths|Logout|10









      share|improve this question















      I am trying to sum certain numbers in a column using awk. I would like to sum just column 3 of the "smiths" to get a total of 212. I can sum the whole column using awk but not just the "smiths". I have:



      awk 'BEGIN FS = " ; sum+=$3 END print sum' filename.txt


      Also I am using putty. Thank you for any help.



      smiths|Login|2
      olivert|Login|10
      denniss|Payroll|100
      smiths|Time|200
      smiths|Logout|10






      linux awk






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 14 '15 at 7:12









      RobertL

      4,798624




      4,798624










      asked Nov 14 '15 at 4:56









      jake

      370139




      370139




















          4 Answers
          4






          active

          oldest

          votes

















          up vote
          57
          down vote



          accepted










          awk -F '|' '$1 ~ /smiths/ sum += $3 END print sum' inputfilename


          • The -F flag sets the field separator; I put it in single quotes because it is a special shell character.

          • Then $1 ~ /smiths/ applies the following code block only to lines where the first field matches the regex /smiths/.

          • The rest is the same as your code.

          Note that since you're not really using a regex here, just a specific value, you could just as easily use:



          awk -F '|' '$1 == "smiths" sum += $3 END print sum' inputfilename


          Which checks string equality. This is equivalent to using the regex /^smiths$/, as mentioned in another answer, which includes the ^ anchor to only match the start of the string (the start of field 1) and the $ anchor to only match the end of the string. Not sure how familiar you are with regexes. They are very powerful, but for this case you could use a string equality check just as easily.






          share|improve this answer


















          • 3




            By the way, my go-to favorite awk reference is grymoire.com/Unix/Awk.html. Very helpful page.
            – Wildcard
            Nov 14 '15 at 5:10






          • 1




            Thank you @Wildcard ! I was able to neatly aggregate a uncompressed size of particular files in big zip archive based on your advice :) unzip -lv /appl/tmp/data.lar | grep documentlibrary | awk 'sum += $1 END print sum/1024/1024'
            – Pawel
            Dec 12 '17 at 11:24


















          up vote
          13
          down vote













          Another approach is to use awk associative arrays, more info here. This line produces the desired output:



          awk -F '|' 'a[$1] += $3 ENDprint a["smiths"]' filename.txt


          As a side effect, the array stores all other values:



          awk -F '|' 'a[$1] += $3 ENDfor (i in a) print i, a[i]' filename.txt


          Output:



          smiths 212
          denniss 100
          olivert 10





          share|improve this answer




















          • This is the right answer
            – PoVa
            Mar 24 at 13:17

















          up vote
          5
          down vote













          Very good so far. All you need to do is add a selector before the block to add the sum. Here we check that the first argument contains only "smiths":



          awk 'BEGIN FS = " ; $1 ~ /^smiths$/ sum+=$3 END print sum'


          You could shorten this a bit by specifying the field separator as an option. In awk it's generally a good idea to initialize variables on the command line:



          awk -F'|' '$1 ~ /^smiths$/ sum+=$3 END print sum'





          share|improve this answer





























            up vote
            0
            down vote













            cat filename.txt | grep smiths | awk -F '|' 'sum+=$NF END print sum'



            • -F option to specify separator.


            • $NF is for "last column".





            share|improve this answer




















            • cat and grep are unnecessary here.
              – Andrey
              Apr 18 at 13:29










            Your Answer








            StackExchange.ready(function()
            var channelOptions =
            tags: "".split(" "),
            id: "106"
            ;
            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',
            convertImagesToLinks: false,
            noModals: true,
            showLowRepImageUploadWarning: true,
            reputationToPostImages: null,
            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%2funix.stackexchange.com%2fquestions%2f242946%2fusing-awk-to-sum-the-values-of-a-column-based-on-the-values-of-another-column%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








            up vote
            57
            down vote



            accepted










            awk -F '|' '$1 ~ /smiths/ sum += $3 END print sum' inputfilename


            • The -F flag sets the field separator; I put it in single quotes because it is a special shell character.

            • Then $1 ~ /smiths/ applies the following code block only to lines where the first field matches the regex /smiths/.

            • The rest is the same as your code.

            Note that since you're not really using a regex here, just a specific value, you could just as easily use:



            awk -F '|' '$1 == "smiths" sum += $3 END print sum' inputfilename


            Which checks string equality. This is equivalent to using the regex /^smiths$/, as mentioned in another answer, which includes the ^ anchor to only match the start of the string (the start of field 1) and the $ anchor to only match the end of the string. Not sure how familiar you are with regexes. They are very powerful, but for this case you could use a string equality check just as easily.






            share|improve this answer


















            • 3




              By the way, my go-to favorite awk reference is grymoire.com/Unix/Awk.html. Very helpful page.
              – Wildcard
              Nov 14 '15 at 5:10






            • 1




              Thank you @Wildcard ! I was able to neatly aggregate a uncompressed size of particular files in big zip archive based on your advice :) unzip -lv /appl/tmp/data.lar | grep documentlibrary | awk 'sum += $1 END print sum/1024/1024'
              – Pawel
              Dec 12 '17 at 11:24















            up vote
            57
            down vote



            accepted










            awk -F '|' '$1 ~ /smiths/ sum += $3 END print sum' inputfilename


            • The -F flag sets the field separator; I put it in single quotes because it is a special shell character.

            • Then $1 ~ /smiths/ applies the following code block only to lines where the first field matches the regex /smiths/.

            • The rest is the same as your code.

            Note that since you're not really using a regex here, just a specific value, you could just as easily use:



            awk -F '|' '$1 == "smiths" sum += $3 END print sum' inputfilename


            Which checks string equality. This is equivalent to using the regex /^smiths$/, as mentioned in another answer, which includes the ^ anchor to only match the start of the string (the start of field 1) and the $ anchor to only match the end of the string. Not sure how familiar you are with regexes. They are very powerful, but for this case you could use a string equality check just as easily.






            share|improve this answer


















            • 3




              By the way, my go-to favorite awk reference is grymoire.com/Unix/Awk.html. Very helpful page.
              – Wildcard
              Nov 14 '15 at 5:10






            • 1




              Thank you @Wildcard ! I was able to neatly aggregate a uncompressed size of particular files in big zip archive based on your advice :) unzip -lv /appl/tmp/data.lar | grep documentlibrary | awk 'sum += $1 END print sum/1024/1024'
              – Pawel
              Dec 12 '17 at 11:24













            up vote
            57
            down vote



            accepted







            up vote
            57
            down vote



            accepted






            awk -F '|' '$1 ~ /smiths/ sum += $3 END print sum' inputfilename


            • The -F flag sets the field separator; I put it in single quotes because it is a special shell character.

            • Then $1 ~ /smiths/ applies the following code block only to lines where the first field matches the regex /smiths/.

            • The rest is the same as your code.

            Note that since you're not really using a regex here, just a specific value, you could just as easily use:



            awk -F '|' '$1 == "smiths" sum += $3 END print sum' inputfilename


            Which checks string equality. This is equivalent to using the regex /^smiths$/, as mentioned in another answer, which includes the ^ anchor to only match the start of the string (the start of field 1) and the $ anchor to only match the end of the string. Not sure how familiar you are with regexes. They are very powerful, but for this case you could use a string equality check just as easily.






            share|improve this answer














            awk -F '|' '$1 ~ /smiths/ sum += $3 END print sum' inputfilename


            • The -F flag sets the field separator; I put it in single quotes because it is a special shell character.

            • Then $1 ~ /smiths/ applies the following code block only to lines where the first field matches the regex /smiths/.

            • The rest is the same as your code.

            Note that since you're not really using a regex here, just a specific value, you could just as easily use:



            awk -F '|' '$1 == "smiths" sum += $3 END print sum' inputfilename


            Which checks string equality. This is equivalent to using the regex /^smiths$/, as mentioned in another answer, which includes the ^ anchor to only match the start of the string (the start of field 1) and the $ anchor to only match the end of the string. Not sure how familiar you are with regexes. They are very powerful, but for this case you could use a string equality check just as easily.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Jan 4 at 16:36









            KiriSakow

            54




            54










            answered Nov 14 '15 at 5:05









            Wildcard

            22.6k961164




            22.6k961164







            • 3




              By the way, my go-to favorite awk reference is grymoire.com/Unix/Awk.html. Very helpful page.
              – Wildcard
              Nov 14 '15 at 5:10






            • 1




              Thank you @Wildcard ! I was able to neatly aggregate a uncompressed size of particular files in big zip archive based on your advice :) unzip -lv /appl/tmp/data.lar | grep documentlibrary | awk 'sum += $1 END print sum/1024/1024'
              – Pawel
              Dec 12 '17 at 11:24













            • 3




              By the way, my go-to favorite awk reference is grymoire.com/Unix/Awk.html. Very helpful page.
              – Wildcard
              Nov 14 '15 at 5:10






            • 1




              Thank you @Wildcard ! I was able to neatly aggregate a uncompressed size of particular files in big zip archive based on your advice :) unzip -lv /appl/tmp/data.lar | grep documentlibrary | awk 'sum += $1 END print sum/1024/1024'
              – Pawel
              Dec 12 '17 at 11:24








            3




            3




            By the way, my go-to favorite awk reference is grymoire.com/Unix/Awk.html. Very helpful page.
            – Wildcard
            Nov 14 '15 at 5:10




            By the way, my go-to favorite awk reference is grymoire.com/Unix/Awk.html. Very helpful page.
            – Wildcard
            Nov 14 '15 at 5:10




            1




            1




            Thank you @Wildcard ! I was able to neatly aggregate a uncompressed size of particular files in big zip archive based on your advice :) unzip -lv /appl/tmp/data.lar | grep documentlibrary | awk 'sum += $1 END print sum/1024/1024'
            – Pawel
            Dec 12 '17 at 11:24





            Thank you @Wildcard ! I was able to neatly aggregate a uncompressed size of particular files in big zip archive based on your advice :) unzip -lv /appl/tmp/data.lar | grep documentlibrary | awk 'sum += $1 END print sum/1024/1024'
            – Pawel
            Dec 12 '17 at 11:24













            up vote
            13
            down vote













            Another approach is to use awk associative arrays, more info here. This line produces the desired output:



            awk -F '|' 'a[$1] += $3 ENDprint a["smiths"]' filename.txt


            As a side effect, the array stores all other values:



            awk -F '|' 'a[$1] += $3 ENDfor (i in a) print i, a[i]' filename.txt


            Output:



            smiths 212
            denniss 100
            olivert 10





            share|improve this answer




















            • This is the right answer
              – PoVa
              Mar 24 at 13:17














            up vote
            13
            down vote













            Another approach is to use awk associative arrays, more info here. This line produces the desired output:



            awk -F '|' 'a[$1] += $3 ENDprint a["smiths"]' filename.txt


            As a side effect, the array stores all other values:



            awk -F '|' 'a[$1] += $3 ENDfor (i in a) print i, a[i]' filename.txt


            Output:



            smiths 212
            denniss 100
            olivert 10





            share|improve this answer




















            • This is the right answer
              – PoVa
              Mar 24 at 13:17












            up vote
            13
            down vote










            up vote
            13
            down vote









            Another approach is to use awk associative arrays, more info here. This line produces the desired output:



            awk -F '|' 'a[$1] += $3 ENDprint a["smiths"]' filename.txt


            As a side effect, the array stores all other values:



            awk -F '|' 'a[$1] += $3 ENDfor (i in a) print i, a[i]' filename.txt


            Output:



            smiths 212
            denniss 100
            olivert 10





            share|improve this answer












            Another approach is to use awk associative arrays, more info here. This line produces the desired output:



            awk -F '|' 'a[$1] += $3 ENDprint a["smiths"]' filename.txt


            As a side effect, the array stores all other values:



            awk -F '|' 'a[$1] += $3 ENDfor (i in a) print i, a[i]' filename.txt


            Output:



            smiths 212
            denniss 100
            olivert 10






            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Nov 14 '15 at 7:51









            Andrey

            430214




            430214











            • This is the right answer
              – PoVa
              Mar 24 at 13:17
















            • This is the right answer
              – PoVa
              Mar 24 at 13:17















            This is the right answer
            – PoVa
            Mar 24 at 13:17




            This is the right answer
            – PoVa
            Mar 24 at 13:17










            up vote
            5
            down vote













            Very good so far. All you need to do is add a selector before the block to add the sum. Here we check that the first argument contains only "smiths":



            awk 'BEGIN FS = " ; $1 ~ /^smiths$/ sum+=$3 END print sum'


            You could shorten this a bit by specifying the field separator as an option. In awk it's generally a good idea to initialize variables on the command line:



            awk -F'|' '$1 ~ /^smiths$/ sum+=$3 END print sum'





            share|improve this answer


























              up vote
              5
              down vote













              Very good so far. All you need to do is add a selector before the block to add the sum. Here we check that the first argument contains only "smiths":



              awk 'BEGIN FS = " ; $1 ~ /^smiths$/ sum+=$3 END print sum'


              You could shorten this a bit by specifying the field separator as an option. In awk it's generally a good idea to initialize variables on the command line:



              awk -F'|' '$1 ~ /^smiths$/ sum+=$3 END print sum'





              share|improve this answer
























                up vote
                5
                down vote










                up vote
                5
                down vote









                Very good so far. All you need to do is add a selector before the block to add the sum. Here we check that the first argument contains only "smiths":



                awk 'BEGIN FS = " ; $1 ~ /^smiths$/ sum+=$3 END print sum'


                You could shorten this a bit by specifying the field separator as an option. In awk it's generally a good idea to initialize variables on the command line:



                awk -F'|' '$1 ~ /^smiths$/ sum+=$3 END print sum'





                share|improve this answer














                Very good so far. All you need to do is add a selector before the block to add the sum. Here we check that the first argument contains only "smiths":



                awk 'BEGIN FS = " ; $1 ~ /^smiths$/ sum+=$3 END print sum'


                You could shorten this a bit by specifying the field separator as an option. In awk it's generally a good idea to initialize variables on the command line:



                awk -F'|' '$1 ~ /^smiths$/ sum+=$3 END print sum'






                share|improve this answer














                share|improve this answer



                share|improve this answer








                edited Nov 14 '15 at 5:08

























                answered Nov 14 '15 at 5:02









                RobertL

                4,798624




                4,798624




















                    up vote
                    0
                    down vote













                    cat filename.txt | grep smiths | awk -F '|' 'sum+=$NF END print sum'



                    • -F option to specify separator.


                    • $NF is for "last column".





                    share|improve this answer




















                    • cat and grep are unnecessary here.
                      – Andrey
                      Apr 18 at 13:29














                    up vote
                    0
                    down vote













                    cat filename.txt | grep smiths | awk -F '|' 'sum+=$NF END print sum'



                    • -F option to specify separator.


                    • $NF is for "last column".





                    share|improve this answer




















                    • cat and grep are unnecessary here.
                      – Andrey
                      Apr 18 at 13:29












                    up vote
                    0
                    down vote










                    up vote
                    0
                    down vote









                    cat filename.txt | grep smiths | awk -F '|' 'sum+=$NF END print sum'



                    • -F option to specify separator.


                    • $NF is for "last column".





                    share|improve this answer












                    cat filename.txt | grep smiths | awk -F '|' 'sum+=$NF END print sum'



                    • -F option to specify separator.


                    • $NF is for "last column".






                    share|improve this answer












                    share|improve this answer



                    share|improve this answer










                    answered Jul 11 '17 at 10:10









                    forzagreen

                    12117




                    12117











                    • cat and grep are unnecessary here.
                      – Andrey
                      Apr 18 at 13:29
















                    • cat and grep are unnecessary here.
                      – Andrey
                      Apr 18 at 13:29















                    cat and grep are unnecessary here.
                    – Andrey
                    Apr 18 at 13:29




                    cat and grep are unnecessary here.
                    – Andrey
                    Apr 18 at 13:29

















                    draft saved

                    draft discarded
















































                    Thanks for contributing an answer to Unix & Linux Stack Exchange!


                    • 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%2funix.stackexchange.com%2fquestions%2f242946%2fusing-awk-to-sum-the-values-of-a-column-based-on-the-values-of-another-column%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






                    Popular posts from this blog

                    Peggy Mitchell

                    Palaiologos

                    The Forum (Inglewood, California)