如何将用“:”分隔的IP和端口存储到两个变量中?

Den*_*isZ 6 bash

我想从变量中提取 IP 和端口。我尝试过使用这个:

ADDR=1.2.3.4:12345
IP=${ADDR##:}
PORT=${ADDR%:}
Run Code Online (Sandbox Code Playgroud)

但是,这会将整个地址分配给两个变量。

如何将 IP 和端口存储到两个变量?

Art*_*ild 15

你错了,应该是这样的:

ADDR=1.2.3.4:12345
IP=${ADDR%:*}
PORT=${ADDR##*:}
Run Code Online (Sandbox Code Playgroud)

由于 IPv4 仅出现一次匹配:,因此在这种情况下,匹配第一个或最后一个出现并不重要。但是,对于 IPv6,最好匹配最后一次出现的端口。另外,看来你不小心切换了IP和PORT。

另请参阅此处:Bash 备忘单Bash Hacker wiki

简而言之,子字符串删除的工作原理如下:

  • ${variable#pattern}:从字符串开头删除第一个匹配项
  • ${variable##pattern}:从字符串开头删除最后一个匹配项
  • ${variable%pattern}:从字符串末尾删除,第一个匹配
  • ${variable%%pattern}:从字符串末尾删除最后一个匹配项

*如果您只想匹配单词的一部分(不以空格分隔),则可能需要在模式中包含通配符 ( )。

  • 如果您有新问题,请提出新问题。谢谢。 (3认同)
  • +1 对于此任务来说,一个合适的扩展是替换,即 `${Var//pattern/replacement}` ...例如 `${ADDR//*:/}` 和 `${ADDR//:*/ }` ...如果您想将 `:` 与端口一起保留,例如 `${ADDR//*:/:}` ,这可能会很方便 (2认同)

Raf*_*ffa 7

由于您的字符串没有空格,也没有 shell 全局变量,即:

\n
addr="1.2.3.4:12345"\n
Run Code Online (Sandbox Code Playgroud)\n

顺便说一句,引用你的字符串是一个很好的做法

\n

您可以简单地使用 IP 和 PORT 填充数组,如下所示:

\n
a=(${addr//\\:/ })\n
Run Code Online (Sandbox Code Playgroud)\n

这会将:字符串中的每个内容替换为 内部的空格(),瞧!现在它是一个数组...这也适用于 MAC 地址之类的内容,但需要更多的数组元素。

\n

注意:这适用于IPv4 \xe2\x80\xa6 对于IPv6,您可以这样做:

\n
addr="[1fff:0:a88:85a3::ac1f]:8001"\naddr="${addr/\\[/}"\na=(${addr/\\]\\:/ })\n
Run Code Online (Sandbox Code Playgroud)\n

或者:您可以自动执行此操作以处理IPv4IPv6,例如,条件如下:

\n
if [[ "$addr" =~ [\\:]{2,} ]]\n  then\n  # It\'s IPv6 ... Do this\n  addr="${addr/\\[/}"\n  a=(${addr/\\]\\:/ })\n  else\n  # It\'s IPv4 ... Do this instead\n  a=(${addr//\\:/ })\n  fi\n
Run Code Online (Sandbox Code Playgroud)\n

然后,您可以像这样调用并打印数组元素:

\n
echo -e "IP: ${a[0]}\\nPORT: ${a[1]}"\n
Run Code Online (Sandbox Code Playgroud)\n

然后像这样简单地使用它:

\n
$ addr="1.2.3.4:12345"\n$ a=(${addr//:/ })\n$ echo -e "IP: ${a[0]}\\nPORT: ${a[1]}"\nIP: 1.2.3.4\nPORT: 12345\n
Run Code Online (Sandbox Code Playgroud)\n

或者像这样处理空端口或没有端口:

\n
$ addr="1.2.3.4:" # or even addr="1.2.3.4"\n$ a=(${addr//:/ })\n$ echo -e "IP: ${a[0]}\\nPORT: ${a[1]:-EMPTY}"\nIP: 1.2.3.4\nPORT: EMPTY\n
Run Code Online (Sandbox Code Playgroud)\n

就操作和评估而言......请参阅下面的演示:

\n
$ addr="1.2.3.4:12345"\n$ # Populating an array "a" with the elements around the ":" from the string in "$addr"\na=(${addr//:/ })\n$ # Assigning array "a" elements to parameters\nip="${a[0]}"\nport="${a[1]}"\n$ # Assigning array "a" length(number of elements) to a parameter\nlen="${#a[@]}"\n$ # Printing array length\necho "${#a[@]}"\necho "$len"\n2\n2\n$ # Printing all array "a" elements\necho "${a[@]}"\n1.2.3.4 12345\n$ # Printing array "a" elements by index\necho "IP: ${a[0]} and PORT: ${a[1]}"\nIP: 1.2.3.4 and PORT: 12345\n$ # Printing array elements from parameters\necho "IP: $ip and PORT: $port"\nIP: 1.2.3.4 and PORT: 12345\n$ # Evaluating by array length\n[ "${#a[@]}" == "2" ] && echo "IP: $ip and PORT: $port" || echo "IP: $ip and PORT: NA"\n[ "$len" == "2" ] && echo "IP: $ip and PORT: $port" || echo "IP: $ip and PORT: NA"\nIP: 1.2.3.4 and PORT: 12345\nIP: 1.2.3.4 and PORT: 12345\n$ # Evaluating by array element/parameter string length "-z"(zero)\n[ -z "${a[1]}" ] && echo "IP: ${a[0]} and PORT: NA" || echo "IP: ${a[0]} and PORT: ${a[1]}"\n[ -z "$port" ] && echo "IP: $ip and PORT: NA" || echo "IP: $ip and PORT: $port"\nIP: 1.2.3.4 and PORT: 12345\nIP: 1.2.3.4 and PORT: 12345\n$ \n$ \n$ # This is a demonstration when there is only IP4 and no port \n$ addr="1.2.3.4"\n$ a=(${addr//:/ })\n$ ip="${a[0]}"\nport="${a[1]}"\n$ len="${#a[@]}"\n$ echo "${#a[@]}"\necho "$len"\n1\n1\n$ echo "${a[@]}"\n1.2.3.4\n$ echo "IP: ${a[0]} and PORT: ${a[1]}"\nIP: 1.2.3.4 and PORT: \n$ echo "IP: $ip and PORT: $port"\nIP: 1.2.3.4 and PORT: \n$ [ "${#a[@]}" == "2" ] && echo "IP: $ip and PORT: $port" || echo "IP: $ip and PORT: NA"\n[ "$len" == "2" ] && echo "IP: $ip and PORT: $port" || echo "IP: $ip and PORT: NA"\nIP: 1.2.3.4 and PORT: NA\nIP: 1.2.3.4 and PORT: NA\n$ [ -z "${a[1]}" ] && echo "IP: ${a[0]} and PORT: NA" || echo "IP: ${a[0]} and PORT: ${a[1]}"\n[ -z "$port" ] && echo "IP: $ip and PORT: NA" || echo "IP: $ip and PORT: $port"\nIP: 1.2.3.4 and PORT: NA\nIP: 1.2.3.4 and PORT: NA\n
Run Code Online (Sandbox Code Playgroud)\n

注意:虽然这个arr=(${parameter//delimiter/ })hack 是一个简单而好的事情,知道它可以完美地工作,如上所述,但你应该知道,如果你的字符串包含空格,它也容易出现 shell 分词,如果你的字符串包含通配符,它​​也容易出现 shell 通配符字符例如*...所以不建议这样做。

\n


ste*_*ver 6

这是使用 bash 内置read命令的另一种方法:

IFS=: read IP PORT <<<"$ADDR"
Run Code Online (Sandbox Code Playgroud)

前任。(您应该避免为自己的 shell 变量使用全大写名称 - 它们是非正式保留的):

$ addr=1.2.3.4:12345
$ IFS=: read ip port <<<"$addr"
$ printf 'IP is %s and PORT is %s\n' "$ip" "${port:-EMPTY}"
IP is 1.2.3.4 and PORT is 12345
Run Code Online (Sandbox Code Playgroud)

此方法还将处理 :PORT 丢失的情况:

$ addr=1.2.3.4
$ IFS=: read ip port <<<"$addr"
$ printf 'IP is %s and PORT is %s\n' "$ip" "${port:-EMPTY}"
IP is 1.2.3.4 and PORT is EMPTY
Run Code Online (Sandbox Code Playgroud)