1

I have a unsorted list of integers; say

1
2
3
3
4
5
5
2

I want to sort the list, and then calculate cumulative sum until the sum reaches a pre-defined integer; say 17. After stopping, it should print the last integer which added up to exceed the pre-defined integer. See example

My sorted list will be:

5
5
4
3
3
2
2
1

5+5+4+3=17, so the cumulative sum will stop here and will print the last integer which is '3'

I tried this with no luck :(

 awk 'BEGIN {sum=0} {sum= sum+$0; if (sum >= '$pre-defined_integer') print $0}
lakhujanivijay
  • 107
  • 2
  • 11
  • The script is fine, you are only failing in using the var. Just say `-v var="$pre_defined_integer" '{... if (sum >= var) print }'` – fedorqui Jan 10 '17 at 12:01
  • there is still the sort problem that is not "simple" use of variable in this case if a piped sort is not used in command line – NeronLeVelu Jan 10 '17 at 12:21

1 Answers1

1
$ cat add.txt
5
5
4
3
3
2
2
1

$ pre_defined_integer=17

$ awk -v pdi=$pre_defined_integer '{sum += $0; if (sum >= pdi) {print; exit}}' add.txt
3

More or less you had it. For correctness I think you were just missing the exit so that you didn't keep printing after reaching the pre-defined limit.

But other things to note:

  • Most importantly, the best way to use variables from the shell is to pass them to awk via the -v option.

And a few small things:

  • The BEGIN block isn't really necessary since awk initializes variables to zero.
  • x += y can be used in place of x = x + y
  • print $0 can simply be written as print
jas
  • 10,715
  • 2
  • 30
  • 41
  • same concept (still not sorted as OP ask) so not another reply `awk -v pdi=${pre_defined_integer} '(sum+=$1) >= pdi {print;exit}' add.txt` – NeronLeVelu Jan 10 '17 at 12:04
  • `pre_defined_integer=17 awk -v pdi=${pre_defined_integer} '{vs[NR] = $1} END{ asort(vs,ss) for( i=1; i<=NR && ( (Sum+=vs[ss[i]]) <= pdi);)i++ print vs[ss[i]] }' addt.txt ` only work with gnu awk due to sorti function not in posix awk – NeronLeVelu Jan 10 '17 at 12:20