LinuxQuestions.org
Review your favorite Linux distribution.
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 02-26-2015, 02:02 PM   #1
new2bash
LQ Newbie
 
Registered: Jan 2014
Posts: 15

Rep: Reputation: 0
Unhappy Trying to count # of times an 'if' statement is true in a loop.


I just have no idea how to do what I'm looking for here. I have a simple script (see below) that pings a list of sites from a separate text file. I want to count how many times the pings fail -per site-. I understand how to count total failures, but I have no clue how to keep the count separate for each site.

Bash script
Code:
#!/bin/bash

for i in {1..3600}
do
clear ; echo -e "Interval $i"

while IFS=, read name ip
do

ping -c 1 $ip >/dev/null 2>&1

if [ $? -ne 0 ] ; then
                echo -e "\e[31;1mName: $name\t$ip  \t- down.\e[0m\tCount: ___"

        else

                echo -e "\e[32;1mName: $name\t$ip  \t- up!\e[0m\tCount: ___"
fi

done < ~/monitor.txt

#  30 sec Countdown Timer
for i in {30..1};do echo -ne "\r$i" && sleep 1;echo -ne "\r   "; done

done


Sample csv text file
Code:
google,8.8.8.8
nat,10.1.1.1
Sample Output My goal is to have "Count ___" = the number of times site x failed.
http://i.imgur.com/Jwd2YRW.png
 
Old 02-27-2015, 12:12 AM   #2
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,006

Rep: Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191
Assuming recent version of bash (4+) you could use associative arrays:
Code:
declare -A count

echo $((count[name]++))
This is assuming your variable called 'name'
 
Old 04-01-2015, 06:08 AM   #3
new2bash
LQ Newbie
 
Registered: Jan 2014
Posts: 15

Original Poster
Rep: Reputation: 0
Quote:
Originally Posted by grail View Post
Assuming recent version of bash (4+) you could use associative arrays:
Code:
declare -A count

echo $((count[name]++))
This is assuming your variable called 'name'
Thanks, but where would I add this?

I don't see how this adds to "count" only when a test(ping) fails, or how it keeps a separate tally for each item in the list. I've tried googling around for the answer and have hit a brick wall.

Last edited by new2bash; 04-01-2015 at 06:30 AM.
 
Old 04-01-2015, 06:28 AM   #4
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 21,830

Rep: Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308
what do you want to count? You need to insert it next to the echo ... down line I think.
 
Old 04-01-2015, 06:33 AM   #5
new2bash
LQ Newbie
 
Registered: Jan 2014
Posts: 15

Original Poster
Rep: Reputation: 0
Quote:
Originally Posted by pan64 View Post
what do you want to count? You need to insert it next to the echo ... down line I think.
As the OP states, I am trying to count the number of times the test(ping) fails for each item(IP) in the test list. I need the counts to be separate.

For example
Name: google 8.8.8.8 - Up! Count: 0
Name: nat 10.1.1.1 - down. Count: 2

*Count should only increment on fails.
 
Old 04-01-2015, 06:36 AM   #6
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 21,830

Rep: Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308
I think you misunderstood my question: You need to insert that line exactly where you want to count something...
 
Old 04-01-2015, 06:46 AM   #7
new2bash
LQ Newbie
 
Registered: Jan 2014
Posts: 15

Original Poster
Rep: Reputation: 0
Quote:
Originally Posted by pan64 View Post
I think you misunderstood my question: You need to insert that line exactly where you want to count something...
Here's how the script reads with that addition...

Code:

#!/bin/bash

# Declare 'count' array.
declare -A count

for i in {1..3600}
do
clear ; echo -e "Interval $i"

while IFS=, read name ip
do

ping -c 1 $ip >/dev/null 2>&1

if [ $? -ne 0 ] ; then
                echo -e "\e[31;1mName: $name\t$ip  \t- down.\e[0m\tCount: $((count[name]++))"

        else

                echo -e "\e[32;1mName: $name\t$ip  \t- up!\e[0m\tCount: $((count[name]))"
fi

done < ~/monitor.txt

#  30 sec Countdown Timer
for i in {30..1};do echo -ne "\r$i" && sleep 1;echo -ne "\r   "; done

done
Only the "down"(fail) line adds to the count. However this only has one(1) counter. There are multiple IP's being tested and ALL fails are being added together. I need them in increment separately.

Current output (assuming "nat" fails 3 times out of 10...and "google" never fails)
Name: google 8.8.8.8 - Up! Count: 3
Name: nat 10.1.1.1 - down. Count: 3

What I need is:
Name: google 8.8.8.8 - Up! Count: 0
Name: nat 10.1.1.1 - down. Count: 3

Last edited by new2bash; 04-01-2015 at 06:49 AM.
 
Old 04-01-2015, 07:04 AM   #8
pan64
LQ Addict
 
Registered: Mar 2012
Location: Hungary
Distribution: debian/ubuntu/suse ...
Posts: 21,830

Rep: Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308Reputation: 7308
try to use two arrays: $((count_up[name]++)) and also count_down
 
Old 04-01-2015, 07:20 AM   #9
michaelk
Moderator
 
Registered: Aug 2002
Posts: 25,698

Rep: Reputation: 5895Reputation: 5895Reputation: 5895Reputation: 5895Reputation: 5895Reputation: 5895Reputation: 5895Reputation: 5895Reputation: 5895Reputation: 5895Reputation: 5895
Quote:
$((count[name]++))
name in this context is a constant and not a variable.

Try
$(( count[$name]++ ))
 
Old 04-01-2015, 09:34 AM   #10
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,006

Rep: Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191
If you are not interested in the up count and wish this to always be zero, then do not include the counter in the up portion just us a static zero.
Of course if you are interested in both up and down, then pan64's suggestion is the way to go.

@michaelk - did you try it? I think you will find that like inside (()) when a variable is inside [] for an array it is actually evaluated.

oops ... apologies michaelk, I forgot this was an associative array and not a numeric one ... you are correct that it needs the $ to draw the string from it

Last edited by grail; 04-01-2015 at 09:53 AM. Reason: I made a boo boo
 
Old 04-01-2015, 09:58 AM   #11
michaelk
Moderator
 
Registered: Aug 2002
Posts: 25,698

Rep: Reputation: 5895Reputation: 5895Reputation: 5895Reputation: 5895Reputation: 5895Reputation: 5895Reputation: 5895Reputation: 5895Reputation: 5895Reputation: 5895Reputation: 5895
Code:
#!/bin/bash
declare -A count

name=me

echo $(( count[name]++ ))

name=foo
echo $(( count[name]++ ))


echo "count[me]" $(( count[me] ))
echo "count[foo]" $(( count[foo] ))
echo "count[name]" $(( count[name] ))
echo

name=me

echo $(( count[$name]++ ))

name=foo
echo $(( count[$name]++ ))

echo

echo "count[me]"  $(( count[me] ))
echo "count[foo]" $(( count[foo] ))
echo "count[name]" $(( count[name] ))
Code:
0
1
count[me] 0
count[foo] 0
count[name] 2

0
0

count[me] 1
count[foo] 1
count[name] 2
Or did I miss something...
 
Old 04-01-2015, 10:32 AM   #12
michaelk
Moderator
 
Registered: Aug 2002
Posts: 25,698

Rep: Reputation: 5895Reputation: 5895Reputation: 5895Reputation: 5895Reputation: 5895Reputation: 5895Reputation: 5895Reputation: 5895Reputation: 5895Reputation: 5895Reputation: 5895
In addition adding first as below will display the actual error count as the OP posted the script.

$(( ++count[$name] ))
 
Old 04-02-2015, 12:30 AM   #13
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,006

Rep: Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191Reputation: 3191
Quote:
Originally Posted by michaelk
Or did I miss something...
Yes ... my apology
 
Old 04-02-2015, 01:10 AM   #14
new2bash
LQ Newbie
 
Registered: Jan 2014
Posts: 15

Original Poster
Rep: Reputation: 0
This must be a lot harder than I expected as none of these seem to resolve the question.
 
Old 04-02-2015, 01:21 AM   #15
new2bash
LQ Newbie
 
Registered: Jan 2014
Posts: 15

Original Poster
Rep: Reputation: 0
I'm trying to make my question as simple as possible as I'm assuming people just aren't understanding the desired outcome.

1) The script reads a text(CSV) list of names and IP's.
2) The first IP on the list is pinged.
3)
---a--- IF down the script prints "Name <ip> - down Count: 1
---b--- IF up, the script prints "Name <ip> - up Count: 0
* 0 fails so far
4) The script now pings the next IP on the list.
---a--- IF down the script prints "Name <ip> - down Count: 1
---b--- IF up, the script prints "Name <ip> - up Count: 0
The screen now looks like this (assuming the 1st IP was up and the 2nd was down)
Name: google 8.8.8.8 - up! Count: 0
Name: nat 10.1.1.1 - down. Count: 1

5)A brief countdown occurs then the screen clears and the script starts the ping tests again.

* With the changes recommended above I now get...
Name: google 8.8.8.8 - up! Count: 1
Name: nat 10.1.1.1 - down. Count: 2

See the problem? It's combining ALL fails. I need them separate. The desired output would look like this (assuming the 1st item continues passing and the 2nd continues to fail)

Name: google 8.8.8.8 - up! Count: 0
Name: nat 10.1.1.1 - down. Count: 8
 
  


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
[SOLVED] Using while loop & select statement - Loop issues Kustom42 Programming 4 05-17-2013 08:43 AM
[SOLVED] Is the true statement necessary in a simple script? mackes Programming 8 08-28-2012 12:31 PM
LXer: Android Started Before iPhone: How True a Statement is That? LXer Syndicated Linux News 0 11-27-2011 07:51 AM
if statement ignoring true/false and proceeding anyway. Goblin_C_Noob Programming 4 03-30-2008 09:56 AM
Why do I get true in this if statement in bash? nadavvin Programming 4 01-23-2007 12:47 AM

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

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