Since your string has no spaces and no shell globs i.e.:
addr="1.2.3.4:12345"
(It's a good practice to quote your string BTW)
You can simply populate an array with the IP and the PORT like so:
a=(${addr//\:/ })
That will replace each :
in the string with a space
inside the ()
and voila! it's an array now ... That would work for things like MAC addresses as well, but expect more array elements.
Notice: This will work for IPv4 … For IPv6, you can do something like this instead:
addr="[1fff:0:a88:85a3::ac1f]:8001"
addr="${addr/\[/}"
a=(${addr/\]\:/ })
Alternatively: You can automate this to handle both IPv4 and IPv6 with e.g. a condition like this:
if [[ "$addr" =~ [\:]{2,} ]]
then
# It's IPv6 ... Do this
addr="${addr/\[/}"
a=(${addr/\]\:/ })
else
# It's IPv4 ... Do this instead
a=(${addr//\:/ })
fi
And then, you can call and print the array elements like so:
echo -e "IP: ${a[0]}\nPORT: ${a[1]}"
Then simply use it like so:
$ addr="1.2.3.4:12345"
$ a=(${addr//:/ })
$ echo -e "IP: ${a[0]}\nPORT: ${a[1]}"
IP: 1.2.3.4
PORT: 12345
Or to handle empty or no PORT like so:
$ addr="1.2.3.4:" # or even addr="1.2.3.4"
$ a=(${addr//:/ })
$ echo -e "IP: ${a[0]}\nPORT: ${a[1]:-EMPTY}"
IP: 1.2.3.4
PORT: EMPTY
As far as manipulation and evaluation goes ... Please see the demonstration below:
$ addr="1.2.3.4:12345"
$ # Populating an array "a" with the elements around the ":" from the string in "$addr"
a=(${addr//:/ })
$ # Assigning array "a" elements to parameters
ip="${a[0]}"
port="${a[1]}"
$ # Assigning array "a" length(number of elements) to a parameter
len="${#a[@]}"
$ # Printing array length
echo "${#a[@]}"
echo "$len"
2
2
$ # Printing all array "a" elements
echo "${a[@]}"
1.2.3.4 12345
$ # Printing array "a" elements by index
echo "IP: ${a[0]} and PORT: ${a[1]}"
IP: 1.2.3.4 and PORT: 12345
$ # Printing array elements from parameters
echo "IP: $ip and PORT: $port"
IP: 1.2.3.4 and PORT: 12345
$ # Evaluating by array length
[ "${#a[@]}" == "2" ] && echo "IP: $ip and PORT: $port" || echo "IP: $ip and PORT: NA"
[ "$len" == "2" ] && echo "IP: $ip and PORT: $port" || echo "IP: $ip and PORT: NA"
IP: 1.2.3.4 and PORT: 12345
IP: 1.2.3.4 and PORT: 12345
$ # Evaluating by array element/parameter string length "-z"(zero)
[ -z "${a[1]}" ] && echo "IP: ${a[0]} and PORT: NA" || echo "IP: ${a[0]} and PORT: ${a[1]}"
[ -z "$port" ] && echo "IP: $ip and PORT: NA" || echo "IP: $ip and PORT: $port"
IP: 1.2.3.4 and PORT: 12345
IP: 1.2.3.4 and PORT: 12345
$
$
$ # This is a demonstration when there is only IP4 and no port
$ addr="1.2.3.4"
$ a=(${addr//:/ })
$ ip="${a[0]}"
port="${a[1]}"
$ len="${#a[@]}"
$ echo "${#a[@]}"
echo "$len"
1
1
$ echo "${a[@]}"
1.2.3.4
$ echo "IP: ${a[0]} and PORT: ${a[1]}"
IP: 1.2.3.4 and PORT:
$ echo "IP: $ip and PORT: $port"
IP: 1.2.3.4 and PORT:
$ [ "${#a[@]}" == "2" ] && echo "IP: $ip and PORT: $port" || echo "IP: $ip and PORT: NA"
[ "$len" == "2" ] && echo "IP: $ip and PORT: $port" || echo "IP: $ip and PORT: NA"
IP: 1.2.3.4 and PORT: NA
IP: 1.2.3.4 and PORT: NA
$ [ -z "${a[1]}" ] && echo "IP: ${a[0]} and PORT: NA" || echo "IP: ${a[0]} and PORT: ${a[1]}"
[ -z "$port" ] && echo "IP: $ip and PORT: NA" || echo "IP: $ip and PORT: $port"
IP: 1.2.3.4 and PORT: NA
IP: 1.2.3.4 and PORT: NA
Notice: While this arr=(${parameter//delimiter/ })
hack is a simple and nice thing to know that works perfectly as described above, but you should know it's also prone to shell word splitting if your string contains spaces and also prone to shell globbing if your string contains globbing characters e.g *
... So it wouldn't be advised then.