Got stuck earlier in an interesting regex mystery and I command-line FU’d an AWK Solution.
PROBLEM
I want to strip out all spaces and/or special characters from an IP address
PROCESS
I know how to validate an IP address no problem..
Good IPO
# echo 192.168.1.122 |egrep -q '[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}'; echo $?
0
Bad IP
# echo 192.168.xxx.111 |egrep -q '[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}'; echo $?
1
However..
What if am gathering user input via script and I want to strip out any and ALL characters except the numeric IP Address!
For example,
If IP
' _192. 168.122.35'_ "
And I want to only display
192.168.122.35
Leading/trailing spaces can be stripped no problem, but it will still print the special characters
# echo " _192. 168.122.35'_ "|awk '{gsub(/^[[:space:]]+|[[:space:]]+$/,"",$0); print}'
_192. 168.122.35'_
#
SOLUTION
I put together the following awk script to strip out everything and ONLY print the IP address.
awk -F "." '{for (i=1;i<=NF;i++) {sub("[^[:digit:]]+", "", $i);gsub(/^[[:space:]]+|[[:space:]]+$/,"",$i);if (i < NF) {p="."}else{p=""} ;printf $i p}}'
Example
# echo ' _ 192 .168 .120.111 "@ '|awk -F "." '{for (i=1;i<=NF;i++) {sub("[^[:digit:]]+", "", $i);gsub(/^[[:space:]]+|[[:space:]]+$/,"",$i);if (i < NF) {p="."}else{p=""} ;printf $i p}}'
192.168.120.111
#
To put it all together in a quick script called ‘btest’
#!/bin/bash
if [ $# != 0 ]; then
if [ $(echo "$1" |egrep -q '[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}'; echo $?) == 0 ]; then
echo "Validated IP address [$1]"
IP=$(echo "$1"|awk -F "." '{for (i=1;i<=NF;i++) {sub("[^[:digit:]]+", "", $i);gsub(/^[[:space:]]+|[[:space:]]+$/,"",$i);if (i < NF) {p="."}else{p=""} ;printf $i p}}')
echo "Corrected IP Address=$IP"
else
echo "Invalid IP address [$1]"
fi
else
echo "Enter IP address"
fi
If we were to enter an IP address of “192.168.1.11′” which contains a ‘tick’ at the end , the initial Validation would succeed.
But I can then show you how we use awk to strip out any misc characters
# ./btest "192.168.1.11'"
Validated IP address [192.168.1.11']
Corrected IP Address [192.168.1.11]
If we were to add leading and trailing white spaces on the argument we can see that it is still corrected
# ./btest " 192.168.1.11' "
Validated IP address [ 192.168.1.11' ]
Ensuring IP does not have any special characters or spaces
Corrected IP Address [192.168.1.11]
If we type an invalid IP Address we see it is caught
# ./btest " 192.168.1.xx' "
Invalid IP address [ 192.168.1.xx' ]
If I got extra wild and crazy and used the following for an IP address we would see it would still succeed
# ./btest ' _ 192.168.120.111 "@ '
Validated IP address [ _ 192.168.120.111 "@ ]
Corrected IP Address [192.168.120.111]
Now to put it all together into a script that will gather user input
#!/bin/bash
e=0
while [ $e == 0 ]; do
printf "Enter IP address > "
read ip
if [ ! -z "$ip" ]; then
if [ $(echo "$ip" |egrep -q '[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}'; echo $?) == 0 ]; then
echo "Validated IP address [$ip]"
ip=$(echo "$ip"|awk -F "." '{for (i=1;i<=NF;i++) {sub("[^[:digit:]]+", "", $i);gsub(/^[[:space:]]+|[[:space:]]+$/,"",$i);if (i < NF) {p="."}else{p=""} ;printf $i p}}')
echo "Corrected IP Address [$ip]"
e=1
else
echo "Invalid IP address [$ip]"
e=0
fi
else
echo "ERROR: Enter IP address"
fi
done
Example 1
# ./btest
Enter IP address > 192.168.1.222
Validated IP address [192.168.1.222]
Corrected IP Address [192.168.1.222]
Example 2
# ./btest
Enter IP address > '192.168.122.111 '
Validated IP address ['192.168.122.111 ']
Ensuring IP does not have any special characters or spaces
Corrected IP Address [192.168.122.111]