LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 09-22-2018, 05:06 PM   #1
pedropt
Member
 
Registered: Aug 2014
Distribution: Devuan
Posts: 345

Rep: Reputation: Disabled
add all numeric values from variable in a single command


Hi , maybe this is not the right name for this thread , but i was unable to remember anything else for it .

I get a variable with multiples lines with numbers

variable 1 = $var1
Quote:
34
789
285
23
etc ...
The question is how to add all values in a single shot .
If it was a file , then i was able to count the lines and then insert a loop by adding each value to the next one , but even that would gave me issues ahead .

Is there anyway to get an output with the total value from this variable ?

Something like :
34+789+285+23 = 1131 expected as output

The initial variable is not fixed , this means that can have 2 lines only as also can have 10 lines to be counted .

Thanks
 
Old 09-22-2018, 05:28 PM   #2
pedropt
Member
 
Registered: Aug 2014
Distribution: Devuan
Posts: 345

Original Poster
Rep: Reputation: Disabled
I think i got it , i was just stubbling around here on the logic to work this out .
Eventually this will work , but i did not test it out yet because i have other programming to do to this script before running it .
If anyone have a better idea then post it here .

Here it is what came to my mind :
I called the variable with all the numbers to be counted as ipc2
Code:
#Here splits on the echo command line by line the numbers 
# If the numbers on echo are displayed as (34 789 285 23) , then the tr command will put each #one on a single line
a1=$(echo "$ipc2" | tr " " "\n" | wc -l)
# a1 = total number of lines to be added
# Defined out variable as an empty var
out=""
#Start the loop based on the number of lines to be counted before
for i in $(seq "$a1")
do
# read the first line
nmb=$(echo "ipc2" | sed -n ${i}p)

#Here it is the trick , if the out is empty then dont add nothing , just place the first #number
if [[ -z "$out" ]]
then
out="$nmb"
else
#case out variable is not empty then add its value to the one got from nmb var before
out=$((out+"$nmb"))
fi
done 
echo "total vlaue is : $out"
 
Old 09-22-2018, 06:39 PM   #3
syg00
LQ Veteran
 
Registered: Aug 2003
Location: Australia
Distribution: Lots ...
Posts: 21,140

Rep: Reputation: 4123Reputation: 4123Reputation: 4123Reputation: 4123Reputation: 4123Reputation: 4123Reputation: 4123Reputation: 4123Reputation: 4123Reputation: 4123Reputation: 4123
Code:
echo $ipc2 | awk '{for (i=1; i<=NF; i++) sum+=$i} END{print "Total value is: "sum}'
KISS
 
1 members found this post helpful.
Old 09-22-2018, 08:31 PM   #4
lougavulin
Member
 
Registered: Jul 2018
Distribution: Slackware,x86_64,current
Posts: 279

Rep: Reputation: 100Reputation: 100
I would have done it with Awk as syg00.

But with shell, that is not as hard as you do. Just for information :
Code:
SUM=0
for INT in $(echo ${ipc2} | tr -dc '[0-9] '); do
  SUM=$(( INT + SUM ))
done
echo "Total value is: ${SUM}"
The only trick might be tr -dc, which remove everything that is not a number or a space. So your ipc2 variable could be '123 345 abcd &+-' it will still work.
 
1 members found this post helpful.
Old 09-23-2018, 01:50 AM   #5
ondoho
LQ Addict
 
Registered: Dec 2013
Posts: 19,872
Blog Entries: 12

Rep: Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053Reputation: 6053
i question the need to have multiple numeric values in a single variable like that.
can't you use an array instead?
assuming bash or another shell that supports them?
 
1 members found this post helpful.
Old 09-23-2018, 02:19 AM   #6
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,008

Rep: Reputation: 3193Reputation: 3193Reputation: 3193Reputation: 3193Reputation: 3193Reputation: 3193Reputation: 3193Reputation: 3193Reputation: 3193Reputation: 3193Reputation: 3193
I am with ondoho, please show how the "ipc2" variable is being populated?
 
Old 09-23-2018, 02:45 AM   #7
MadeInGermany
Senior Member
 
Registered: Dec 2011
Location: Simplicity
Posts: 2,806

Rep: Reputation: 1207Reputation: 1207Reputation: 1207Reputation: 1207Reputation: 1207Reputation: 1207Reputation: 1207Reputation: 1207Reputation: 1207
Yes, out or SUM should be preset to 0 not ""
And yes, the for loop's list should be the input values, that are separated by IFS (space or tab or newline).
Code:
out=0
for nmb in $ipc2
do
  out=$((out+nmb))
done
bash supports
Code:
  ((out+=nmb))
 
Old 09-23-2018, 03:12 AM   #8
pedropt
Member
 
Registered: Aug 2014
Distribution: Devuan
Posts: 345

Original Poster
Rep: Reputation: Disabled
some how is not working , i have to do a loop inside a loop because it is not stopping , i will be back as soon as i get it working .

Reedited .

Basicaly this is a script to read the serverlog , and count how many times an ip access the server .
So , the serverfile is a raw file that an external tcp monitoring tool is writing all the time as soon as anyone access the server ip no matter witch port is accessed .

With a few commands i can filter all the stuff i dont want to be check in this count , by this i mean dns requests from server , igmp , 224.0.0.1 , requests to the main isp modem gateway ip ,etc

From the raw file i get a new file that is something like this next example :

Quote:
2 1.1.1.1
4 5.5.5.5
1 3.3.3.3
1 1.1.1.1
9 7.7.7.7
6 4.4.4.4
5 2.2.2.2
3 5.5.5.5
The repeated ips on same list means that same ip access the server on different times , by this is means :

Example : ip 1.1.1.1 first time ask 2 requests to server , later ahead made 1 request to server , and go on

Now , my objective is to count how many times an ip access the website and what was doing in the site , by this and very ahead on the script , by the ip address i have a command to check all logs to see what was doing , this way i can ban that specific ip or not if want it .
Some ips are legit , accessing webite normally , others are pentesting , by default the pentesting ips get banned from server on the firewall rules almost at the end of the sript .

Bu returning .
After the first filter i use a loop to read the filtered file (from raw tcp dump) , and read line by line , on reading line by line what i do is :
1st - i get the ip on a variable
2nd - i search from that ip on the filtered file and retrieve the number of accesses

something like this :

Code:
ffile="output"
function count (){
SUM=0
for INT in $(echo ${rdaccess} | tr -dc '[0-9] '); do
  SUM=$(( INT + SUM ))
# echo is a quick helper for me to know if everything is working as expected , it will be removed)
echo "$rdip is $SUM"
done

# Now i will create a new file with everything ring and without repeated ips

# if output file exists then check if the ip is already there ,
# i have to do it this way , because on the loop , the script will count same ip multiples #times in many parts of the filtered file
if [[ -f "$ffile" ]]
then
a1=$(grep "$rdip"< "$ffile")
if [[ -z "$a1" ]]
then
i case the specific ip is not yet in the list then add it to the final file
echo "$SUM $rdip">> $ffile
fi
else
# here is in case the final file does not exist yet , this will write the first ip to it
echo "$SUM $rdip"> $ffile
fi 
}

#tmp is the filtered file from original raw
cntlst=$(wc -l <tmp)
for i in $(seq "$cntlst")
do

#read the first ip
rdip=$(sed -n ${i}p < tmp | awk '{print$2}')

# get all the accesses from that ip in the filtered file
rdaccess=$(grep "$rdip" < tmp | awk '{print$1}')

# at this point rdaccess variable only have the accesses numbers from Quote added before

# count is a subfunction where it will count all the rdaccess variable numbers
count
done

Last edited by pedropt; 09-23-2018 at 03:40 AM.
 
Old 09-23-2018, 03:49 AM   #9
pedropt
Member
 
Registered: Aug 2014
Distribution: Devuan
Posts: 345

Original Poster
Rep: Reputation: Disabled
Well , i got it working , like it is in the previous code , it toke sometime because filtered file have 2,4M of data to be counted , and this took sometime
 
Old 09-23-2018, 04:37 AM   #10
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 21,930

Rep: Reputation: 7321Reputation: 7321Reputation: 7321Reputation: 7321Reputation: 7321Reputation: 7321Reputation: 7321Reputation: 7321Reputation: 7321Reputation: 7321Reputation: 7321
it is far from optimal. Instead of:
Code:
cntlst=$(wc -l <tmp)
for i in $(seq "$cntlst")
do

#read the first ip
rdip=$(sed -n ${i}p < tmp | awk '{print$2}')

# get all the accesses from that ip in the filtered file
rdaccess=$(grep "$rdip" < tmp | awk '{print$1}')

# at this point rdaccess variable only have the accesses numbers from Quote added before

# count is a subfunction where it will count all the rdaccess variable numbers
count
done
you can try something like:
Code:
while read -r _ rdip;
do
# get all the accesses from that ip in the filtered file
rdaccess=$(awk "/$rdip/"'{print $1}' tmp)

# at this point rdaccess variable only have the accesses numbers from Quote added before

# count is a subfunction where it will count all the rdaccess variable numbers
count
done < tmp
I have not tested it (but will be definitely faster)
And it can be still improved if awk will do that count function.

Last edited by pan64; 09-23-2018 at 04:39 AM.
 
Old 09-23-2018, 09:24 AM   #11
pedropt
Member
 
Registered: Aug 2014
Distribution: Devuan
Posts: 345

Original Poster
Rep: Reputation: Disabled
Thanks to all , after a few adjustments to the script and adding more things to it here it is the output :

https://i.imgur.com/j2AYCBJ.png

The first question is to ask to user after how many ip accesses he wants the script to display the results , because there are hundreds of inputs with 1 or 2 accesses , witch are normally legit and almost dont need to be checked .

This is just the script that prompts to user what is happening in the webserver inputs and give him an idea how to follow next , ahead this script comes another that searches the log files for that ip entries and display it to user so he can decide if that ip gets banned or not , and it makes changes to the firewall settings in real time .

Probably in future i will upgrade it if i get some time to a new level where statistics from target ip will retrieve ports accesses and witch files , etc....

Again , thanks for the help .
 
Old 09-23-2018, 09:32 AM   #12
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 21,930

Rep: Reputation: 7321Reputation: 7321Reputation: 7321Reputation: 7321Reputation: 7321Reputation: 7321Reputation: 7321Reputation: 7321Reputation: 7321Reputation: 7321Reputation: 7321
I think even better to do something like this:
Code:
awk '{sum[$2] += $1 }
     END { for (i in sum) {
           print i,":",sum[i];
     } }' inputfile | sort -n | head
(again, not tested)
 
  


Reply



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
changing variables to numeric values budgie26 Linux - General 6 01-30-2013 01:11 AM
bash: how to compare REAL numeric values? muebi Linux - General 3 02-28-2012 08:00 AM
Using multiple values for single variable in a loop rockf1bull Red Hat 1 12-07-2011 01:53 PM
BASH scripting: check for numeric values linuxLuser Programming 11 11-14-2011 10:11 AM
Searching for numeric values in PHP TheBeli Programming 5 04-17-2008 03:55 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 10:35 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