LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices


Reply
  Search this Thread
Old 07-19-2020, 07:03 PM   #1
Drosera_capensis
Member
 
Registered: Jun 2018
Posts: 124

Rep: Reputation: Disabled
Make a countdown column with awk


Hello everyone,

A little question about awk.
Given a column of numbers in a "list" file.
0
1
2
3
4
5

I wish to print a list displaying (sum - value) at each row, as a countdown of the sum of the first list.
15
13
10
6
1
0

I have tried to set up a script to do it, but it does not work.

Code:
cat list |  awk ' BEGIN {S+=$1} END {a=$1} {print (S-$a)}'
Would anyone has a solution for this?

Last edited by Drosera_capensis; 07-19-2020 at 07:08 PM.
 
Old 07-19-2020, 07:47 PM   #2
syg00
LQ Veteran
 
Registered: Aug 2003
Location: Australia
Distribution: Lots ...
Posts: 19,473

Rep: Reputation: 3453Reputation: 3453Reputation: 3453Reputation: 3453Reputation: 3453Reputation: 3453Reputation: 3453Reputation: 3453Reputation: 3453Reputation: 3453Reputation: 3453
BEGIN block is only entered once - likewise the END block; one right at the start, one right at the finish. You don't need the BEGIN. There are other logic errors, but that is for you to solve.
 
Old 07-19-2020, 07:49 PM   #3
berndbausch
LQ Addict
 
Registered: Nov 2013
Location: Tokyo
Distribution: A few
Posts: 6,062

Rep: Reputation: 1884Reputation: 1884Reputation: 1884Reputation: 1884Reputation: 1884Reputation: 1884Reputation: 1884Reputation: 1884Reputation: 1884Reputation: 1884Reputation: 1884
The action at the END is meaningless, since there is no $1 at the END and you do nothing with variable "a".
Similarly, there is no $1 at the BEGINning.
The print action is executed at each input line, but there is no such thing as $a in awk. I suppose you get syntax errors and the program doesn't even start running.

Now, I don't really understand how to correlate the input and output, otherwise I could give you hints how to construct the awk program. 15 is obviously the sum of all numbers, but how do you compute 13? I would have expected 14 there (sum is 15, value is 1, sum-value is 14).

EDIT: In any case, you need two passes over the file, since you need to know the sum of all numbers when processing the first line.

Last edited by berndbausch; 07-19-2020 at 07:55 PM.
 
Old 07-19-2020, 07:51 PM   #4
berndbausch
LQ Addict
 
Registered: Nov 2013
Location: Tokyo
Distribution: A few
Posts: 6,062

Rep: Reputation: 1884Reputation: 1884Reputation: 1884Reputation: 1884Reputation: 1884Reputation: 1884Reputation: 1884Reputation: 1884Reputation: 1884Reputation: 1884Reputation: 1884
Oh, and you commit cat abuse, too.
 
Old 07-19-2020, 08:06 PM   #5
scasey
LQ Veteran
 
Registered: Feb 2013
Location: Tucson, AZ, USA
Distribution: CentOS 7.8.2003
Posts: 5,360

Rep: Reputation: 2006Reputation: 2006Reputation: 2006Reputation: 2006Reputation: 2006Reputation: 2006Reputation: 2006Reputation: 2006Reputation: 2006Reputation: 2006Reputation: 2006
Quote:
Originally Posted by berndbausch View Post
Now, I don't really understand how to correlate the input and output, otherwise I could give you hints how to construct the awk program. 15 is obviously the sum of all numbers, but how do you compute 13? I would have expected 14 there (sum is 15, value is 1, sum-value is 14).
I donít understand either...looks to me like the result needs to be:
15
10
6
3
1
0
Pseudo code:
Get the sum of all lines...print it
Read through the list in reverse order
Subtract the amount on each line from the total and print the result.

Homework??
 
Old 07-20-2020, 04:43 AM   #6
Drosera_capensis
Member
 
Registered: Jun 2018
Posts: 124

Original Poster
Rep: Reputation: Disabled
Thank you for your comments.
There is indeed a mistake in my example.
The input:
0
1
2
3
4
5

The output:
15
14
12
9
5
0

It makes more sense now!
syg00 here is my explanation of the use of BEGIN and END.

For the formula:
I produce a sum of the columns with {S+=$1}. I add BEGIN for this operation would be done before the others.
I then record the value of column 1 in the variable a. It is quoted $a afterward to indicate it is a variable.
Finally, I print the subtraction sum_of_the_column - $a. I have added END for these operations to be done after the sum.

scasey what you describe is exactly why I have tried to do.
I am aware that if no one recognize the formula it is very far from the solution.
I will search for another way to design this script.

Last edited by Drosera_capensis; 07-20-2020 at 05:00 AM.
 
Old 07-20-2020, 05:01 AM   #7
pan64
LQ Guru
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 15,948

Rep: Reputation: 5279Reputation: 5279Reputation: 5279Reputation: 5279Reputation: 5279Reputation: 5279Reputation: 5279Reputation: 5279Reputation: 5279Reputation: 5279Reputation: 5279
Quote:
Originally Posted by Drosera_capensis View Post
I don't know what to do, I have been working with awk for one year now, and I am still as bad as when I started.
You need to understand how awk works.
awk is something like a for loop (like sed/grep and other "similar" apps). I mean they take one line at once, and process the input line by line.
So the awk (grep/sed/...) script will be executed on every and each line.
BEGIN and END are two keywords. BEGIN and END blocks will be executed only once, before the first line an after the last. (ok, there is an exception where we have more than one input files, but you can ignore it right now).

From the other hand the 15 is the total sum of those numbers, you need to process all the lines to get it.
To get the result list you need to process all the lines once more.

This is the second half:
Code:
awk -vX=15 '{X-=$1; print X}' a.list
 
1 members found this post helpful.
Old 07-20-2020, 05:18 AM   #8
shruggy
Senior Member
 
Registered: Mar 2020
Posts: 1,738

Rep: Reputation: Disabled
Quote:
Originally Posted by pan64 View Post
To get the result list you need to process all the lines once more.
@OP. And Turbocapitalist once already explained to you how to do this.
 
1 members found this post helpful.
Old 07-20-2020, 05:41 AM   #9
Drosera_capensis
Member
 
Registered: Jun 2018
Posts: 124

Original Poster
Rep: Reputation: Disabled
Much thanks to your answer pan64.
Here is a script that I have set up based on yours.
I was unaware that variables ($a here) were not usable in the awk command, and that -v was used to input variables.
That was what berndbausch was referring to with $a, without quoting it literally.

Quote:
a=$(awk ' {sum=sum+$1}END{print sum}' list)
awk -vX=$a '{X-=$1; print X}' list
Thank you shruggy, I have forgotten this post which is less than three months old. It is indeed the exact same problem.
I tend to forget a lot.
I will find tutorials and will try to train on awk daily, else I will forget again.
Thanks for your help.
 
Old 07-20-2020, 05:44 AM   #10
pan64
LQ Guru
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 15,948

Rep: Reputation: 5279Reputation: 5279Reputation: 5279Reputation: 5279Reputation: 5279Reputation: 5279Reputation: 5279Reputation: 5279Reputation: 5279Reputation: 5279Reputation: 5279
glad to help you.
If you really want to say thanks just click on yes.
 
Old 07-20-2020, 07:07 AM   #11
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 9,809

Rep: Reputation: 3069Reputation: 3069Reputation: 3069Reputation: 3069Reputation: 3069Reputation: 3069Reputation: 3069Reputation: 3069Reputation: 3069Reputation: 3069Reputation: 3069
Now that you seem to have a process that works for you.

May I suggest you look at your awk manual you are using, or this one if you do not,
and try placing the numbers in an array whilst summing your total and then you can simply use your END block to unpack the array in the order you like and subtract at will
 
Old 07-20-2020, 10:17 AM   #12
allend
LQ 5k Club
 
Registered: Oct 2003
Location: Melbourne
Distribution: Slackware-current
Posts: 5,513

Rep: Reputation: 2112Reputation: 2112Reputation: 2112Reputation: 2112Reputation: 2112Reputation: 2112Reputation: 2112Reputation: 2112Reputation: 2112Reputation: 2112Reputation: 2112
To achieve the required output, it is easier to store the running totals (from s+=$1) into an array (with t[NR]=s), then use the END block to subtract each running total from the final sum (with {(for i in t) {print s-t[i]}} ).
 
Old 07-20-2020, 10:29 AM   #13
shruggy
Senior Member
 
Registered: Mar 2020
Posts: 1,738

Rep: Reputation: Disabled
@allend. Even saving the running totals is not needed. I believe what grail implied above was
Code:
awk '{s+=$1;_[$1]}END{for(i in _)print i,s-i}'

Last edited by shruggy; 07-20-2020 at 10:35 AM.
 
1 members found this post helpful.
Old 07-20-2020, 10:46 AM   #14
MadeInGermany
Senior Member
 
Registered: Dec 2011
Location: Simplicity
Posts: 1,621

Rep: Reputation: 732Reputation: 732Reputation: 732Reputation: 732Reputation: 732Reputation: 732Reputation: 732
You can let awk read the input twice. At the first pass (where NR equals FNR) sum up and jump to the next input cycle (skipping the following code).
At the second pass run the following code.
Code:
awk 'NR==FNR { X+=$1; next } { X-=$1; print X }' list list
 
  


Reply

Tags
awk


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
LXer: How to make a countdown timer in bash. LXer Syndicated Linux News 0 02-17-2019 10:34 PM
[SOLVED] AWK - How to parse a Web log file to count column and the last occurrence of that column Alvin88 Linux - Newbie 10 06-23-2017 06:59 AM
[SOLVED] AWK fill column from previuos line column akeka Programming 4 01-30-2013 08:16 PM
[SOLVED] Once again... awk.. awk... awk shivaa Linux - Newbie 13 12-31-2012 05:56 AM
awk multiple column into single column ilukacevic Programming 49 07-19-2010 08:23 PM

LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie

All times are GMT -5. The time now is 04:56 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration