Home > Software design >  How to extract the port number from a listen address
How to extract the port number from a listen address

Time:10-07

I'd like to extract the port number from an address string. The whole string looks like this:

connect single-cluster --listen-addr=127.0.0.1:12345 --filename=hello

or

connect single-cluster --listen-addr=127.0.0.1 --filename=hello

I'd like to save the address and port from the listen-addr to two variables: ADDR and PORT. If the port does not exist in the input string, just leave the PORT variable empty, and set the ADDR.

Now if the port number exists in the input string, I can use this regex:

ORI_STR="connect single-cluster --listen-addr=127.0.0.1:12345 --filename=hello"

LISTEN_ADDR_REGEX="(^|[[:space:]])--listen-addr=(([^[:space:]] ):([^[:space:]] ))($|[[:space:]])"

[[ $ORI_STR =~ $LISTEN_ADDR_REGEX ]] && ADDR=${BASH_REMATCH[3]} && PORT=${BASH_REMATCH[4]}

echo "ADDR=$ADDR"
echo "PORT=$PORT"

This gives me:

ADDR=127.0.0.1
PORT=12345

But I don't know how to include the case that the port number is not set in the original string. (i.e. there's no :12345 in the ORI_STR).

CodePudding user response:

This works with or without the port:

LISTEN_ADDR_REGEX="(^|[[:space:]])--listen-addr=(([^[:space:]:] )(:([^[:space:]] ))?)($|[[:space:]])"
#                                                            ^   ^                ^^

[[ $ORI_STR =~ $LISTEN_ADDR_REGEX ]] && ADDR=${BASH_REMATCH[3]} && PORT=${BASH_REMATCH[5]}
#                                                                                      ^

echo "ADDR=$ADDR"
echo "PORT=$PORT"

I added parentheses around the :port part and marked it optional with ?. That moved the port from match group 4 to 5. I also added : to the exclusion list for the IP address; without that the IP was greedily matching the port.

It's kind of hard to spot the differences so I marked them with ^ carets.

CodePudding user response:

A ? means zero or one match.

#!/usr/bin/env bash

#ori_str="connect single-cluster --listen-addr=127.0.0.1:12345 --filename=hello"

ori_str="connect single-cluster --listen-addr=127.0.0.1 --filename=hello"

listen_addr_regex="^.* --listen-addr=([^:] )(:)?([^[:space:]] )? .*$"

[[ $ori_str =~ $listen_addr_regex ]] && addr=${BASH_REMATCH[1]} && port=${BASH_REMATCH[3]}

echo "addr=$addr"
echo "port=$port"

  • Use "${port:-none}" to use none as the default value or change none to something else if needed
  • Related