How to check if any IP address is present in a file using shell scripting?

I have a script that generates some output. I want to check that output for any IP address like

159.143.23.12
134.12.178.131
124.143.12.132

if (IPs are found in <file>)
then // bunch of actions //
else // bunch of actions //

Is fgrep a good idea?

I have bash available.

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

Yes , You have lot of options/tools to use. I just tried this , it works:

ifconfig | grep -oE "b([0-9]{1,3}.){3}[0-9]{1,3}b"

so you can use grep -oE "b([0-9]{1,3}.){3}[0-9]{1,3}b" to grep the ip addresses from your output.

Method 2

If your file is called e.g ips you can write somethinng like:

while read -r ip
    do
        if [[ $ip == "$1" ]]; then
            shift
            printf '%sn' 'action to take if match found'
        else
            printf '%sn' 'action to take if match not found'
        fi
    done < ips

Then you can pass the parameters as follow the the script

./myscript 159.143.23.12 134.12.178.131 124.143.12.132 124.143.12.132

Method 3

starting my answer based on this answer:

Yes , You have lot of options/tools to use. I just tried this , it
works:

ifconfig | grep -oE “b([0-9]{1,3}.){3}[0-9]{1,3}b”
a
so you can use grep -oE “b([0-9]{1,3}.){3}[0-9]{1,3}b” to grep the
ip addresses from your output.

and converting the answer to full length IPv6, etc…:

fgrep -oE "b([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4}b" -- file

if you want to keep the /nnn if it’s there:

fgrep -oE "b([0-9A-Fa-f]{1,4}:){7}[0-9A-Fa-f]{1,4}(/[0-9]{1,3}){0,1}b" -- file

and also there’s the shortened version of IPv6 that includes ‘::’.

for more IPv6 answers you can look here:
https://stackoverflow.com/questions/53497/regular-expression-that-matches-valid-ipv6-addresses

Method 4

Tested in SmartOS (a variant of Solaris), hopefully should work in other *nix environments:

egrep '(([0-9]|[0-9]{2}|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([0-9]|[0-9]{2}|1[0-9]{2}|2[0-4][0-9]|25[0-5])'

Example:

$ cat >file.txt
IP1: 192.168.1.1
IP2: 261.480.201.311
IP3: 1012.680.921.3411

$ egrep '(([0-9]|[0-9]{2}|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([0-9]|[0-9]{2}|1[0-9]{2}|2[0-4][0-9]|25[0-5])' file.txt
IP1: 192.168.1.1

This pattern matches only valid IPv4, i.e, x.x.x.x where x range from 0-255. Should you need to extract only the matched IP, add an -o option to the above command. You could embed this command in a bash script and presumably in other shell scripts as well. And, if egrep fails, try grep -E ...

Using it in a (bash) shell script:

ip=$(egrep -o '(([0-9]|[0-9]{2}|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([0-9]|[0-9]{2}|1[0-9]{2}|2[0-4][0-9]|25[0-5])' file.txt)
echo $ip

Method 5

If you have the list of IPs in a file, one per line, grep already has the convenient -f option:

$ man fgrep | grep file= -A1
       -f FILE, --file=FILE
              Obtain patterns from FILE, one per line.  The empty file contains zero patterns, and therefore matches nothing.  (-f is specified by POSIX.)

This may cause a few false positives due to strings optionally followed by another number to make it a different IP. Lots of things you can do about it, depending on your case you may or may not decide to worry.

Method 6

ip -4  addr show eth1 |  grep -oP '(?<=inets)d+(.d+){3}'

Method 7

I think my answer to another post is better suited here. Thanks to this post and others like it I came up with this, that looks for the correct IP format, then gets rid of all the lines that contain 256 or higher. Replace the IP with something that is non-valid to see no output instead:

echo '255.154.12.231' | grep -E '(([0-9]{1,3}).){3}([0-9]{1,3}){1}' | grep -vE '25[6-9]|2[6-9][0-9]|[3-9][0-9][0-9]'

The first grep was probably found in this post and it checks for any numbers from 0-999 in the format X.X.X.X

The second grep removes lines with numbers 256-999, thus leaving only valid format IPs, so I thought

BUT…
As pointed out by G-Man, I was in error by assuming the IP would be on its own line. Most always though, there will be a space or another divider to look for on either side of the IP. The spaces/dividers can be removed with sed or other means after the IP is found. I also added -o to the first grep:

echo ' 1234.5.5.4321 ' | grep -Eo ' (([0-9]{1,3}).){3}([0-9]{1,3}){1} ' | grep -vE '25[6-9]|2[6-9][0-9]|[3-9][0-9][0-9]' | sed 's/ //'

echo ' 234.5.5.432 ' | grep -Eo ' (([0-9]{1,3}).){3}([0-9]{1,3}){1} ' | grep -vE '25[6-9]|2[6-9][0-9]|[3-9][0-9][0-9]' | sed 's/ //'
echo ' 234.5.5.100 ' | grep -Eo ' (([0-9]{1,3}).){3}([0-9]{1,3}){1} ' | grep -vE '25[6-9]|2[6-9][0-9]|[3-9][0-9][0-9]' | sed 's/ //'

The first and second will give no output, while the third does and the spaces are stripped.

Method 8

Here is the short form

grep -oE "b(d{1,3}.){3}d{1,3}b"

d is for digits [0-9]

Method 9

Redirect that output to some outputFile

Simply grep it with pattern as,

grep -sE "159.143.23.12|134.12.178.131|124.143.12.132" <outputFile>


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x