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

Clash Royale CLAN TAG#URR8PPP
up vote
48
down vote
favorite
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
add a comment |
up vote
48
down vote
favorite
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
add a comment |
up vote
48
down vote
favorite
up vote
48
down vote
favorite
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
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
linux awk
edited Nov 14 '15 at 7:12
RobertL
4,798624
4,798624
asked Nov 14 '15 at 4:56
jake
370139
370139
add a comment |
add a comment |
4 Answers
4
active
oldest
votes
up vote
57
down vote
accepted
awk -F '|' '$1 ~ /smiths/ sum += $3 END print sum' inputfilename
- The
-Fflag 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.
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
add a comment |
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
This is the right answer
– PoVa
Mar 24 at 13:17
add a comment |
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'
add a comment |
up vote
0
down vote
cat filename.txt | grep smiths | awk -F '|' 'sum+=$NF END print sum'
-Foption to specify separator.$NFis for "last column".
catandgrepare unnecessary here.
– Andrey
Apr 18 at 13:29
add a comment |
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
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
-Fflag 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.
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
add a comment |
up vote
57
down vote
accepted
awk -F '|' '$1 ~ /smiths/ sum += $3 END print sum' inputfilename
- The
-Fflag 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.
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
add a comment |
up vote
57
down vote
accepted
up vote
57
down vote
accepted
awk -F '|' '$1 ~ /smiths/ sum += $3 END print sum' inputfilename
- The
-Fflag 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.
awk -F '|' '$1 ~ /smiths/ sum += $3 END print sum' inputfilename
- The
-Fflag 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.
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
add a comment |
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
add a comment |
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
This is the right answer
– PoVa
Mar 24 at 13:17
add a comment |
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
This is the right answer
– PoVa
Mar 24 at 13:17
add a comment |
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
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
answered Nov 14 '15 at 7:51
Andrey
430214
430214
This is the right answer
– PoVa
Mar 24 at 13:17
add a comment |
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
add a comment |
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'
add a comment |
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'
add a comment |
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'
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'
edited Nov 14 '15 at 5:08
answered Nov 14 '15 at 5:02
RobertL
4,798624
4,798624
add a comment |
add a comment |
up vote
0
down vote
cat filename.txt | grep smiths | awk -F '|' 'sum+=$NF END print sum'
-Foption to specify separator.$NFis for "last column".
catandgrepare unnecessary here.
– Andrey
Apr 18 at 13:29
add a comment |
up vote
0
down vote
cat filename.txt | grep smiths | awk -F '|' 'sum+=$NF END print sum'
-Foption to specify separator.$NFis for "last column".
catandgrepare unnecessary here.
– Andrey
Apr 18 at 13:29
add a comment |
up vote
0
down vote
up vote
0
down vote
cat filename.txt | grep smiths | awk -F '|' 'sum+=$NF END print sum'
-Foption to specify separator.$NFis for "last column".
cat filename.txt | grep smiths | awk -F '|' 'sum+=$NF END print sum'
-Foption to specify separator.$NFis for "last column".
answered Jul 11 '17 at 10:10
forzagreen
12117
12117
catandgrepare unnecessary here.
– Andrey
Apr 18 at 13:29
add a comment |
catandgrepare 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
add a comment |
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.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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