Piduna
Piduna

Reputation: 175

How to count number of times a specific result/output is seen in bash

i have a script of getting of A-records of all IP-s from my network.

    #!/bin/bash

    host_starting=test
    dns=test.com

    for hosts in "${host_starting}"{1..200}."$dns"; do
    addr=`dig +short $hosts`
    echo "$addr=$hosts"
    done

I have output:

192.168.1.1=test1.test.com
192.168.1.2=test2.test.com
192.168.1.3=test3.test.com
192.168.1.4=test4.test.com
192.168.1.5=test5.test.com
192.168.1.6=test6.test.com
192.168.1.7=test7.test.com
192.168.1.8=test8.test.com
192.168.1.9=test9.test.com
192.168.1.10=test10.test.com
10.1.1.1=test11.test.com
10.1.1.1=test12.test.com
...
...
...
a lot of 10.1.1.1

I don't want to show "10.1.1.1". I can resolve it:

if [ $addr != "10.1.1.1" ]; then

But, how can i calculate addresses and make condition: if count of "10.1.1.1" repeats more than 2, we should not show it address.

Upvotes: 0

Views: 113

Answers (2)

Charles Duffy
Charles Duffy

Reputation: 295766

If you only want this behavior for specific IPs

#!/bin/bash

# Only IP addresses preinitialized in this associative array are tracked
declare -A seen=( [10.1.1.1]=0 )

host_prefix=test
dns=test.com

for host in "$host_prefix"{1..200}."$dns"; do
  addr=$(dig +short "$host")
  [[ ${seen[$addr]} ]] && {
    (( seen[$addr] += 1 ))
    (( seen[$addr] > 1 )) && continue
  }
  printf '%s\n' "$addr=$host"
done

# Just for the fun of it, let's dump our counters to stderr...
declare -p seen >&2

If you want this behavior for every IP

#!/bin/bash

declare -A seen=( )

host_prefix=test
dns=test.com

for host in "$host_prefix"{1..200}."$dns"; do
  addr=$(dig +short "$host")
  (( seen[$addr] += 1 ))
  (( ${seen[$addr]} > 1 )) && continue
  printf '%s\n' "$addr=$host"
done

# Just for the fun of it, let's dump our counters to stderr...
declare -p seen >&2

General Notes

declare -A seen defines an array where the indexes are strings, not integers.

(( seen[$addr] += 1 )) increments the counter associated with the address in $addr by one; an empty key is evaluated as 0.

[[ ${seen[$addr]} ]] looks up the entry, if any exists, with the index addr, and returns a truthy value if that entry maps to a non-empty string.

Upvotes: 1

user1934428
user1934428

Reputation: 22311

Not tested, but maybe something like this:

occured_for_instance_at=
special_ip=10.1.1.1
for hosts in "${host_starting}"{1..200}."$dns"; do
    addr=`dig +short $hosts`
    if [[ $addr == $special_ip ]]
    then
      occured_for_instance_at=$hosts
    else
      echo "$addr=$hosts"
    fi
done
[[ -n "$occured_for_instance_at ]] && echo "$special_ip=$occured_for_instance_at"

If you don't mind getting an empty output line in the case that 10.1.1.1 doesn't show up, you could simplify it to:

special_ip_line=
for hosts in "${host_starting}"{1..200}."$dns"; do
    addr=`dig +short $hosts`
    if [[ $addr == 10.1.1.1 ]]
    then
      special_ip_line="$addr=$hosts"
    else
      echo "$addr=$hosts"
    fi
done
echo "$special_ip_line"

Upvotes: 0

Related Questions