Is there any way to quickly and efficiently get a count of IP host addresses in thousands of CIDR/netmask...












4















I am using IPSet to managed tens of thousands of IPv4 CIDR/netmask ranges that then get linked to IPTables rules. This setup is working great, but I would like to get a good, high-level overview count of the IP host addresses IPSet acts on for client reporting purposes.



The IPSet entry formatting is consistently like this:



123.456.0.0/16 timeout 86400


So I can grep on the lines that have timeout to get values to act on the CIDR/netmask ranges that the entry contains.



For example, if I save the IPSet output (via ipset -L -n > ipset-20181228.txt) to a text file named ipset-20181228.txt and then run a combination of grep and wc -l like this:



grep  "timeout" ipset-20181228.txt  | wc -l


I get a count of 39,000+ items which equate to 39,000+ CIDR/netmask ranges. But that is (of course) only counting the CIDR/netmask ranges and not full counts of IP host addresses in that range.



I attempted to use prips (which expands CIDR/netmask values to actual IP addresses in Bash) with grep to cull out only items with CIDR/netmask ranges like this:



grep -oE '(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])/([0-9]{1,2})' ipset-20181228.txt | awk 'NF { system( "prips " $0)  }' | wc -l


And after a whopping 20 to 30 minutes (!!!) on my 2018 MacBook Air (with the fans kicking in), the count I got was 736,000,000+ which is what I am going for… But 20 to 30 minutes is way too long. I want this to be as scriptable and non-intrusive as possible, and can’t trust a command like that to run on a production server without eating up resources; I mean look at how it behaves on my local 2018 MacBook Air development setup.



Is there any way to just calculate the CIDR/netmask range count based on simply the CIDR/netmask value? I am hoping there is just some command line tool—or option in existing tools I am using—that I am unaware of that can help.










share|improve this question

























  • Which conversion do you want? Option A. 1.2.3.0/24 to 1.2.3.0-1.2.3.255 Option B. 1.2.3.0-1.2.3.255 to 1.2.3.0/24. Nmap, traceroute has some features.

    – Biswapriyo
    Dec 29 '18 at 7:19








  • 1





    @Biswapriyo Neither. Did you even read the question? I am simply asking to get a count of IP addresses based on CIDR/netmask notation. Not convert from one form of range notation to another.

    – JakeGould
    Dec 29 '18 at 12:30








  • 2





    If I understood correctly, you want to know how many hosts are in a given ip/mask pair. The hosts number is 2^(32-mask)-2. The mask represents the net bits, so the other part represents the hosts bits. -2 is for the net address and broadcast ips. If you have ipcalc installed run it to see those information. (Excuse-me if I misunderstood your question).

    – Paulo
    Dec 29 '18 at 12:57






  • 1





    @Paulo: Do not subtract 2; do not assume that each range directly corresponds to a subnet. Routes and filter lists have no correspondence to physical layout – an entry might match just part of a subnet, or cover multiple subnets at once, or even apply to networks which have no concept of "subnet" in the first place (e.g. point-to-point links). And really, whether an address represents a host or not isn't even relevant in filtering. Each prefix has exactly 2^(32-mask) addresses and that's it.

    – grawity
    Dec 29 '18 at 15:58













  • @grawity I see your point, I think I was stuck to the concept of a subnet range. That range from the question can be a range of ips, just like you said. Thanks for clarifying. I subscribe to 2^(32-mask).

    – Paulo
    Dec 29 '18 at 18:21
















4















I am using IPSet to managed tens of thousands of IPv4 CIDR/netmask ranges that then get linked to IPTables rules. This setup is working great, but I would like to get a good, high-level overview count of the IP host addresses IPSet acts on for client reporting purposes.



The IPSet entry formatting is consistently like this:



123.456.0.0/16 timeout 86400


So I can grep on the lines that have timeout to get values to act on the CIDR/netmask ranges that the entry contains.



For example, if I save the IPSet output (via ipset -L -n > ipset-20181228.txt) to a text file named ipset-20181228.txt and then run a combination of grep and wc -l like this:



grep  "timeout" ipset-20181228.txt  | wc -l


I get a count of 39,000+ items which equate to 39,000+ CIDR/netmask ranges. But that is (of course) only counting the CIDR/netmask ranges and not full counts of IP host addresses in that range.



I attempted to use prips (which expands CIDR/netmask values to actual IP addresses in Bash) with grep to cull out only items with CIDR/netmask ranges like this:



grep -oE '(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])/([0-9]{1,2})' ipset-20181228.txt | awk 'NF { system( "prips " $0)  }' | wc -l


And after a whopping 20 to 30 minutes (!!!) on my 2018 MacBook Air (with the fans kicking in), the count I got was 736,000,000+ which is what I am going for… But 20 to 30 minutes is way too long. I want this to be as scriptable and non-intrusive as possible, and can’t trust a command like that to run on a production server without eating up resources; I mean look at how it behaves on my local 2018 MacBook Air development setup.



Is there any way to just calculate the CIDR/netmask range count based on simply the CIDR/netmask value? I am hoping there is just some command line tool—or option in existing tools I am using—that I am unaware of that can help.










share|improve this question

























  • Which conversion do you want? Option A. 1.2.3.0/24 to 1.2.3.0-1.2.3.255 Option B. 1.2.3.0-1.2.3.255 to 1.2.3.0/24. Nmap, traceroute has some features.

    – Biswapriyo
    Dec 29 '18 at 7:19








  • 1





    @Biswapriyo Neither. Did you even read the question? I am simply asking to get a count of IP addresses based on CIDR/netmask notation. Not convert from one form of range notation to another.

    – JakeGould
    Dec 29 '18 at 12:30








  • 2





    If I understood correctly, you want to know how many hosts are in a given ip/mask pair. The hosts number is 2^(32-mask)-2. The mask represents the net bits, so the other part represents the hosts bits. -2 is for the net address and broadcast ips. If you have ipcalc installed run it to see those information. (Excuse-me if I misunderstood your question).

    – Paulo
    Dec 29 '18 at 12:57






  • 1





    @Paulo: Do not subtract 2; do not assume that each range directly corresponds to a subnet. Routes and filter lists have no correspondence to physical layout – an entry might match just part of a subnet, or cover multiple subnets at once, or even apply to networks which have no concept of "subnet" in the first place (e.g. point-to-point links). And really, whether an address represents a host or not isn't even relevant in filtering. Each prefix has exactly 2^(32-mask) addresses and that's it.

    – grawity
    Dec 29 '18 at 15:58













  • @grawity I see your point, I think I was stuck to the concept of a subnet range. That range from the question can be a range of ips, just like you said. Thanks for clarifying. I subscribe to 2^(32-mask).

    – Paulo
    Dec 29 '18 at 18:21














4












4








4


1






I am using IPSet to managed tens of thousands of IPv4 CIDR/netmask ranges that then get linked to IPTables rules. This setup is working great, but I would like to get a good, high-level overview count of the IP host addresses IPSet acts on for client reporting purposes.



The IPSet entry formatting is consistently like this:



123.456.0.0/16 timeout 86400


So I can grep on the lines that have timeout to get values to act on the CIDR/netmask ranges that the entry contains.



For example, if I save the IPSet output (via ipset -L -n > ipset-20181228.txt) to a text file named ipset-20181228.txt and then run a combination of grep and wc -l like this:



grep  "timeout" ipset-20181228.txt  | wc -l


I get a count of 39,000+ items which equate to 39,000+ CIDR/netmask ranges. But that is (of course) only counting the CIDR/netmask ranges and not full counts of IP host addresses in that range.



I attempted to use prips (which expands CIDR/netmask values to actual IP addresses in Bash) with grep to cull out only items with CIDR/netmask ranges like this:



grep -oE '(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])/([0-9]{1,2})' ipset-20181228.txt | awk 'NF { system( "prips " $0)  }' | wc -l


And after a whopping 20 to 30 minutes (!!!) on my 2018 MacBook Air (with the fans kicking in), the count I got was 736,000,000+ which is what I am going for… But 20 to 30 minutes is way too long. I want this to be as scriptable and non-intrusive as possible, and can’t trust a command like that to run on a production server without eating up resources; I mean look at how it behaves on my local 2018 MacBook Air development setup.



Is there any way to just calculate the CIDR/netmask range count based on simply the CIDR/netmask value? I am hoping there is just some command line tool—or option in existing tools I am using—that I am unaware of that can help.










share|improve this question
















I am using IPSet to managed tens of thousands of IPv4 CIDR/netmask ranges that then get linked to IPTables rules. This setup is working great, but I would like to get a good, high-level overview count of the IP host addresses IPSet acts on for client reporting purposes.



The IPSet entry formatting is consistently like this:



123.456.0.0/16 timeout 86400


So I can grep on the lines that have timeout to get values to act on the CIDR/netmask ranges that the entry contains.



For example, if I save the IPSet output (via ipset -L -n > ipset-20181228.txt) to a text file named ipset-20181228.txt and then run a combination of grep and wc -l like this:



grep  "timeout" ipset-20181228.txt  | wc -l


I get a count of 39,000+ items which equate to 39,000+ CIDR/netmask ranges. But that is (of course) only counting the CIDR/netmask ranges and not full counts of IP host addresses in that range.



I attempted to use prips (which expands CIDR/netmask values to actual IP addresses in Bash) with grep to cull out only items with CIDR/netmask ranges like this:



grep -oE '(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])/([0-9]{1,2})' ipset-20181228.txt | awk 'NF { system( "prips " $0)  }' | wc -l


And after a whopping 20 to 30 minutes (!!!) on my 2018 MacBook Air (with the fans kicking in), the count I got was 736,000,000+ which is what I am going for… But 20 to 30 minutes is way too long. I want this to be as scriptable and non-intrusive as possible, and can’t trust a command like that to run on a production server without eating up resources; I mean look at how it behaves on my local 2018 MacBook Air development setup.



Is there any way to just calculate the CIDR/netmask range count based on simply the CIDR/netmask value? I am hoping there is just some command line tool—or option in existing tools I am using—that I am unaware of that can help.







linux bash ip netmask






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Dec 29 '18 at 15:01







JakeGould

















asked Dec 29 '18 at 5:40









JakeGouldJakeGould

31.2k1095138




31.2k1095138













  • Which conversion do you want? Option A. 1.2.3.0/24 to 1.2.3.0-1.2.3.255 Option B. 1.2.3.0-1.2.3.255 to 1.2.3.0/24. Nmap, traceroute has some features.

    – Biswapriyo
    Dec 29 '18 at 7:19








  • 1





    @Biswapriyo Neither. Did you even read the question? I am simply asking to get a count of IP addresses based on CIDR/netmask notation. Not convert from one form of range notation to another.

    – JakeGould
    Dec 29 '18 at 12:30








  • 2





    If I understood correctly, you want to know how many hosts are in a given ip/mask pair. The hosts number is 2^(32-mask)-2. The mask represents the net bits, so the other part represents the hosts bits. -2 is for the net address and broadcast ips. If you have ipcalc installed run it to see those information. (Excuse-me if I misunderstood your question).

    – Paulo
    Dec 29 '18 at 12:57






  • 1





    @Paulo: Do not subtract 2; do not assume that each range directly corresponds to a subnet. Routes and filter lists have no correspondence to physical layout – an entry might match just part of a subnet, or cover multiple subnets at once, or even apply to networks which have no concept of "subnet" in the first place (e.g. point-to-point links). And really, whether an address represents a host or not isn't even relevant in filtering. Each prefix has exactly 2^(32-mask) addresses and that's it.

    – grawity
    Dec 29 '18 at 15:58













  • @grawity I see your point, I think I was stuck to the concept of a subnet range. That range from the question can be a range of ips, just like you said. Thanks for clarifying. I subscribe to 2^(32-mask).

    – Paulo
    Dec 29 '18 at 18:21



















  • Which conversion do you want? Option A. 1.2.3.0/24 to 1.2.3.0-1.2.3.255 Option B. 1.2.3.0-1.2.3.255 to 1.2.3.0/24. Nmap, traceroute has some features.

    – Biswapriyo
    Dec 29 '18 at 7:19








  • 1





    @Biswapriyo Neither. Did you even read the question? I am simply asking to get a count of IP addresses based on CIDR/netmask notation. Not convert from one form of range notation to another.

    – JakeGould
    Dec 29 '18 at 12:30








  • 2





    If I understood correctly, you want to know how many hosts are in a given ip/mask pair. The hosts number is 2^(32-mask)-2. The mask represents the net bits, so the other part represents the hosts bits. -2 is for the net address and broadcast ips. If you have ipcalc installed run it to see those information. (Excuse-me if I misunderstood your question).

    – Paulo
    Dec 29 '18 at 12:57






  • 1





    @Paulo: Do not subtract 2; do not assume that each range directly corresponds to a subnet. Routes and filter lists have no correspondence to physical layout – an entry might match just part of a subnet, or cover multiple subnets at once, or even apply to networks which have no concept of "subnet" in the first place (e.g. point-to-point links). And really, whether an address represents a host or not isn't even relevant in filtering. Each prefix has exactly 2^(32-mask) addresses and that's it.

    – grawity
    Dec 29 '18 at 15:58













  • @grawity I see your point, I think I was stuck to the concept of a subnet range. That range from the question can be a range of ips, just like you said. Thanks for clarifying. I subscribe to 2^(32-mask).

    – Paulo
    Dec 29 '18 at 18:21

















Which conversion do you want? Option A. 1.2.3.0/24 to 1.2.3.0-1.2.3.255 Option B. 1.2.3.0-1.2.3.255 to 1.2.3.0/24. Nmap, traceroute has some features.

– Biswapriyo
Dec 29 '18 at 7:19







Which conversion do you want? Option A. 1.2.3.0/24 to 1.2.3.0-1.2.3.255 Option B. 1.2.3.0-1.2.3.255 to 1.2.3.0/24. Nmap, traceroute has some features.

– Biswapriyo
Dec 29 '18 at 7:19






1




1





@Biswapriyo Neither. Did you even read the question? I am simply asking to get a count of IP addresses based on CIDR/netmask notation. Not convert from one form of range notation to another.

– JakeGould
Dec 29 '18 at 12:30







@Biswapriyo Neither. Did you even read the question? I am simply asking to get a count of IP addresses based on CIDR/netmask notation. Not convert from one form of range notation to another.

– JakeGould
Dec 29 '18 at 12:30






2




2





If I understood correctly, you want to know how many hosts are in a given ip/mask pair. The hosts number is 2^(32-mask)-2. The mask represents the net bits, so the other part represents the hosts bits. -2 is for the net address and broadcast ips. If you have ipcalc installed run it to see those information. (Excuse-me if I misunderstood your question).

– Paulo
Dec 29 '18 at 12:57





If I understood correctly, you want to know how many hosts are in a given ip/mask pair. The hosts number is 2^(32-mask)-2. The mask represents the net bits, so the other part represents the hosts bits. -2 is for the net address and broadcast ips. If you have ipcalc installed run it to see those information. (Excuse-me if I misunderstood your question).

– Paulo
Dec 29 '18 at 12:57




1




1





@Paulo: Do not subtract 2; do not assume that each range directly corresponds to a subnet. Routes and filter lists have no correspondence to physical layout – an entry might match just part of a subnet, or cover multiple subnets at once, or even apply to networks which have no concept of "subnet" in the first place (e.g. point-to-point links). And really, whether an address represents a host or not isn't even relevant in filtering. Each prefix has exactly 2^(32-mask) addresses and that's it.

– grawity
Dec 29 '18 at 15:58







@Paulo: Do not subtract 2; do not assume that each range directly corresponds to a subnet. Routes and filter lists have no correspondence to physical layout – an entry might match just part of a subnet, or cover multiple subnets at once, or even apply to networks which have no concept of "subnet" in the first place (e.g. point-to-point links). And really, whether an address represents a host or not isn't even relevant in filtering. Each prefix has exactly 2^(32-mask) addresses and that's it.

– grawity
Dec 29 '18 at 15:58















@grawity I see your point, I think I was stuck to the concept of a subnet range. That range from the question can be a range of ips, just like you said. Thanks for clarifying. I subscribe to 2^(32-mask).

– Paulo
Dec 29 '18 at 18:21





@grawity I see your point, I think I was stuck to the concept of a subnet range. That range from the question can be a range of ips, just like you said. Thanks for clarifying. I subscribe to 2^(32-mask).

– Paulo
Dec 29 '18 at 18:21










2 Answers
2






active

oldest

votes


















2














If your grep command outputs lines like 123.456.0.0/16, then you need to pipe them to



awk -F / '{ count[$2]++ } END { for (mask in count) total+=count[mask]*2^(32-mask); print total }'


The command only extracts masks (i.e. what is after /) and counts occurrences of each mask. At the end the number of hosts is calculated for each encountered mask (2^(32-mask)), multiplied by the number of occurrences and summed up.



Notes:




  • No sanity check is performed. E.g. input like 1.2.3.4/40 will be accepted, non-integer output will be calculated. Improve your preliminary grep filter if needed.

  • Each range independently contributes to the total number. If your ranges overlap then you will get an inflated result (I think your try with prips was no better in this).






share|improve this answer


























  • This is excellent. Running it as follows works quite quickly and the final command I used this with is: grep -oE '(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])/([0-9]{1,2})' ipset-*.txt | awk -F / '{ count[$2]++ } END { for (mask in count) total+=count[mask]*2^(32-mask); print total }'

    – JakeGould
    Dec 30 '18 at 0:07



















0














I thought something like this would work since the original poster is running grep to get the CIDR from lines with timeout:



awk -F'[ /]' '/timeout/ {hosts+=2^(32-$2)};ENDFILE{print "Hosts number in "FILENAME": "hosts;total+=hosts;hosts=0};END {print "Total: "total}' ipset*.txt


EDIT- The awk program above runs ok only with GNU awk. ENDFILE is a GNU extension.



I guess BSD awk ignores ENDFILE and runs that section if it was part of the main program section.



This is compatible with GNU and BSD awk.



awk -F'[ /]' '{if (filename != FILENAME) hosts=0};/timeout/ {hosts+=2^(32-$2)};{filename=FILENAME;file_total[filename]=hosts};END{for (i in file_total) {print "Hosts number in "i": "file_total[i];total+=file_total[i]};{print "Total: "total};}' ipset*.txt





share|improve this answer


























  • Your revised script works in macOS, but as I explained previously it’s horribly over counting in macOS now as well as Linux: I am getting a hosts number of 8,500,000,000,000+ using your script instead of the expected 736,000,000+ I am using in a live sample test file with the accepted answer as well as prips. Sorry, thanks for the effort but this is not working to say the least.

    – JakeGould
    Dec 30 '18 at 4:33








  • 1





    @jakegould Ok, not a problem at all. Probably I didn't understand the output to filter it correctly. Besides I couldn't get an easy way to install prips and take a look how it works and it's output. Anyway it worth the exercise to get the awk report without any GNU extension.

    – Paulo
    Dec 30 '18 at 4:39











Your Answer








StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "3"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsuperuser.com%2fquestions%2f1388660%2fis-there-any-way-to-quickly-and-efficiently-get-a-count-of-ip-host-addresses-in%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























2 Answers
2






active

oldest

votes








2 Answers
2






active

oldest

votes









active

oldest

votes






active

oldest

votes









2














If your grep command outputs lines like 123.456.0.0/16, then you need to pipe them to



awk -F / '{ count[$2]++ } END { for (mask in count) total+=count[mask]*2^(32-mask); print total }'


The command only extracts masks (i.e. what is after /) and counts occurrences of each mask. At the end the number of hosts is calculated for each encountered mask (2^(32-mask)), multiplied by the number of occurrences and summed up.



Notes:




  • No sanity check is performed. E.g. input like 1.2.3.4/40 will be accepted, non-integer output will be calculated. Improve your preliminary grep filter if needed.

  • Each range independently contributes to the total number. If your ranges overlap then you will get an inflated result (I think your try with prips was no better in this).






share|improve this answer


























  • This is excellent. Running it as follows works quite quickly and the final command I used this with is: grep -oE '(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])/([0-9]{1,2})' ipset-*.txt | awk -F / '{ count[$2]++ } END { for (mask in count) total+=count[mask]*2^(32-mask); print total }'

    – JakeGould
    Dec 30 '18 at 0:07
















2














If your grep command outputs lines like 123.456.0.0/16, then you need to pipe them to



awk -F / '{ count[$2]++ } END { for (mask in count) total+=count[mask]*2^(32-mask); print total }'


The command only extracts masks (i.e. what is after /) and counts occurrences of each mask. At the end the number of hosts is calculated for each encountered mask (2^(32-mask)), multiplied by the number of occurrences and summed up.



Notes:




  • No sanity check is performed. E.g. input like 1.2.3.4/40 will be accepted, non-integer output will be calculated. Improve your preliminary grep filter if needed.

  • Each range independently contributes to the total number. If your ranges overlap then you will get an inflated result (I think your try with prips was no better in this).






share|improve this answer


























  • This is excellent. Running it as follows works quite quickly and the final command I used this with is: grep -oE '(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])/([0-9]{1,2})' ipset-*.txt | awk -F / '{ count[$2]++ } END { for (mask in count) total+=count[mask]*2^(32-mask); print total }'

    – JakeGould
    Dec 30 '18 at 0:07














2












2








2







If your grep command outputs lines like 123.456.0.0/16, then you need to pipe them to



awk -F / '{ count[$2]++ } END { for (mask in count) total+=count[mask]*2^(32-mask); print total }'


The command only extracts masks (i.e. what is after /) and counts occurrences of each mask. At the end the number of hosts is calculated for each encountered mask (2^(32-mask)), multiplied by the number of occurrences and summed up.



Notes:




  • No sanity check is performed. E.g. input like 1.2.3.4/40 will be accepted, non-integer output will be calculated. Improve your preliminary grep filter if needed.

  • Each range independently contributes to the total number. If your ranges overlap then you will get an inflated result (I think your try with prips was no better in this).






share|improve this answer















If your grep command outputs lines like 123.456.0.0/16, then you need to pipe them to



awk -F / '{ count[$2]++ } END { for (mask in count) total+=count[mask]*2^(32-mask); print total }'


The command only extracts masks (i.e. what is after /) and counts occurrences of each mask. At the end the number of hosts is calculated for each encountered mask (2^(32-mask)), multiplied by the number of occurrences and summed up.



Notes:




  • No sanity check is performed. E.g. input like 1.2.3.4/40 will be accepted, non-integer output will be calculated. Improve your preliminary grep filter if needed.

  • Each range independently contributes to the total number. If your ranges overlap then you will get an inflated result (I think your try with prips was no better in this).







share|improve this answer














share|improve this answer



share|improve this answer








edited Dec 30 '18 at 0:05









JakeGould

31.2k1095138




31.2k1095138










answered Dec 29 '18 at 20:27









Kamil MaciorowskiKamil Maciorowski

26k155680




26k155680













  • This is excellent. Running it as follows works quite quickly and the final command I used this with is: grep -oE '(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])/([0-9]{1,2})' ipset-*.txt | awk -F / '{ count[$2]++ } END { for (mask in count) total+=count[mask]*2^(32-mask); print total }'

    – JakeGould
    Dec 30 '18 at 0:07



















  • This is excellent. Running it as follows works quite quickly and the final command I used this with is: grep -oE '(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])/([0-9]{1,2})' ipset-*.txt | awk -F / '{ count[$2]++ } END { for (mask in count) total+=count[mask]*2^(32-mask); print total }'

    – JakeGould
    Dec 30 '18 at 0:07

















This is excellent. Running it as follows works quite quickly and the final command I used this with is: grep -oE '(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])/([0-9]{1,2})' ipset-*.txt | awk -F / '{ count[$2]++ } END { for (mask in count) total+=count[mask]*2^(32-mask); print total }'

– JakeGould
Dec 30 '18 at 0:07





This is excellent. Running it as follows works quite quickly and the final command I used this with is: grep -oE '(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])/([0-9]{1,2})' ipset-*.txt | awk -F / '{ count[$2]++ } END { for (mask in count) total+=count[mask]*2^(32-mask); print total }'

– JakeGould
Dec 30 '18 at 0:07













0














I thought something like this would work since the original poster is running grep to get the CIDR from lines with timeout:



awk -F'[ /]' '/timeout/ {hosts+=2^(32-$2)};ENDFILE{print "Hosts number in "FILENAME": "hosts;total+=hosts;hosts=0};END {print "Total: "total}' ipset*.txt


EDIT- The awk program above runs ok only with GNU awk. ENDFILE is a GNU extension.



I guess BSD awk ignores ENDFILE and runs that section if it was part of the main program section.



This is compatible with GNU and BSD awk.



awk -F'[ /]' '{if (filename != FILENAME) hosts=0};/timeout/ {hosts+=2^(32-$2)};{filename=FILENAME;file_total[filename]=hosts};END{for (i in file_total) {print "Hosts number in "i": "file_total[i];total+=file_total[i]};{print "Total: "total};}' ipset*.txt





share|improve this answer


























  • Your revised script works in macOS, but as I explained previously it’s horribly over counting in macOS now as well as Linux: I am getting a hosts number of 8,500,000,000,000+ using your script instead of the expected 736,000,000+ I am using in a live sample test file with the accepted answer as well as prips. Sorry, thanks for the effort but this is not working to say the least.

    – JakeGould
    Dec 30 '18 at 4:33








  • 1





    @jakegould Ok, not a problem at all. Probably I didn't understand the output to filter it correctly. Besides I couldn't get an easy way to install prips and take a look how it works and it's output. Anyway it worth the exercise to get the awk report without any GNU extension.

    – Paulo
    Dec 30 '18 at 4:39
















0














I thought something like this would work since the original poster is running grep to get the CIDR from lines with timeout:



awk -F'[ /]' '/timeout/ {hosts+=2^(32-$2)};ENDFILE{print "Hosts number in "FILENAME": "hosts;total+=hosts;hosts=0};END {print "Total: "total}' ipset*.txt


EDIT- The awk program above runs ok only with GNU awk. ENDFILE is a GNU extension.



I guess BSD awk ignores ENDFILE and runs that section if it was part of the main program section.



This is compatible with GNU and BSD awk.



awk -F'[ /]' '{if (filename != FILENAME) hosts=0};/timeout/ {hosts+=2^(32-$2)};{filename=FILENAME;file_total[filename]=hosts};END{for (i in file_total) {print "Hosts number in "i": "file_total[i];total+=file_total[i]};{print "Total: "total};}' ipset*.txt





share|improve this answer


























  • Your revised script works in macOS, but as I explained previously it’s horribly over counting in macOS now as well as Linux: I am getting a hosts number of 8,500,000,000,000+ using your script instead of the expected 736,000,000+ I am using in a live sample test file with the accepted answer as well as prips. Sorry, thanks for the effort but this is not working to say the least.

    – JakeGould
    Dec 30 '18 at 4:33








  • 1





    @jakegould Ok, not a problem at all. Probably I didn't understand the output to filter it correctly. Besides I couldn't get an easy way to install prips and take a look how it works and it's output. Anyway it worth the exercise to get the awk report without any GNU extension.

    – Paulo
    Dec 30 '18 at 4:39














0












0








0







I thought something like this would work since the original poster is running grep to get the CIDR from lines with timeout:



awk -F'[ /]' '/timeout/ {hosts+=2^(32-$2)};ENDFILE{print "Hosts number in "FILENAME": "hosts;total+=hosts;hosts=0};END {print "Total: "total}' ipset*.txt


EDIT- The awk program above runs ok only with GNU awk. ENDFILE is a GNU extension.



I guess BSD awk ignores ENDFILE and runs that section if it was part of the main program section.



This is compatible with GNU and BSD awk.



awk -F'[ /]' '{if (filename != FILENAME) hosts=0};/timeout/ {hosts+=2^(32-$2)};{filename=FILENAME;file_total[filename]=hosts};END{for (i in file_total) {print "Hosts number in "i": "file_total[i];total+=file_total[i]};{print "Total: "total};}' ipset*.txt





share|improve this answer















I thought something like this would work since the original poster is running grep to get the CIDR from lines with timeout:



awk -F'[ /]' '/timeout/ {hosts+=2^(32-$2)};ENDFILE{print "Hosts number in "FILENAME": "hosts;total+=hosts;hosts=0};END {print "Total: "total}' ipset*.txt


EDIT- The awk program above runs ok only with GNU awk. ENDFILE is a GNU extension.



I guess BSD awk ignores ENDFILE and runs that section if it was part of the main program section.



This is compatible with GNU and BSD awk.



awk -F'[ /]' '{if (filename != FILENAME) hosts=0};/timeout/ {hosts+=2^(32-$2)};{filename=FILENAME;file_total[filename]=hosts};END{for (i in file_total) {print "Hosts number in "i": "file_total[i];total+=file_total[i]};{print "Total: "total};}' ipset*.txt






share|improve this answer














share|improve this answer



share|improve this answer








edited Dec 30 '18 at 4:25

























answered Dec 29 '18 at 21:52









PauloPaulo

57628




57628













  • Your revised script works in macOS, but as I explained previously it’s horribly over counting in macOS now as well as Linux: I am getting a hosts number of 8,500,000,000,000+ using your script instead of the expected 736,000,000+ I am using in a live sample test file with the accepted answer as well as prips. Sorry, thanks for the effort but this is not working to say the least.

    – JakeGould
    Dec 30 '18 at 4:33








  • 1





    @jakegould Ok, not a problem at all. Probably I didn't understand the output to filter it correctly. Besides I couldn't get an easy way to install prips and take a look how it works and it's output. Anyway it worth the exercise to get the awk report without any GNU extension.

    – Paulo
    Dec 30 '18 at 4:39



















  • Your revised script works in macOS, but as I explained previously it’s horribly over counting in macOS now as well as Linux: I am getting a hosts number of 8,500,000,000,000+ using your script instead of the expected 736,000,000+ I am using in a live sample test file with the accepted answer as well as prips. Sorry, thanks for the effort but this is not working to say the least.

    – JakeGould
    Dec 30 '18 at 4:33








  • 1





    @jakegould Ok, not a problem at all. Probably I didn't understand the output to filter it correctly. Besides I couldn't get an easy way to install prips and take a look how it works and it's output. Anyway it worth the exercise to get the awk report without any GNU extension.

    – Paulo
    Dec 30 '18 at 4:39

















Your revised script works in macOS, but as I explained previously it’s horribly over counting in macOS now as well as Linux: I am getting a hosts number of 8,500,000,000,000+ using your script instead of the expected 736,000,000+ I am using in a live sample test file with the accepted answer as well as prips. Sorry, thanks for the effort but this is not working to say the least.

– JakeGould
Dec 30 '18 at 4:33







Your revised script works in macOS, but as I explained previously it’s horribly over counting in macOS now as well as Linux: I am getting a hosts number of 8,500,000,000,000+ using your script instead of the expected 736,000,000+ I am using in a live sample test file with the accepted answer as well as prips. Sorry, thanks for the effort but this is not working to say the least.

– JakeGould
Dec 30 '18 at 4:33






1




1





@jakegould Ok, not a problem at all. Probably I didn't understand the output to filter it correctly. Besides I couldn't get an easy way to install prips and take a look how it works and it's output. Anyway it worth the exercise to get the awk report without any GNU extension.

– Paulo
Dec 30 '18 at 4:39





@jakegould Ok, not a problem at all. Probably I didn't understand the output to filter it correctly. Besides I couldn't get an easy way to install prips and take a look how it works and it's output. Anyway it worth the exercise to get the awk report without any GNU extension.

– Paulo
Dec 30 '18 at 4:39


















draft saved

draft discarded




















































Thanks for contributing an answer to Super User!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsuperuser.com%2fquestions%2f1388660%2fis-there-any-way-to-quickly-and-efficiently-get-a-count-of-ip-host-addresses-in%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Plaza Victoria

Puebla de Zaragoza

Musa