Unix shell中的命令,以获取“之后的第二个数值”-&引用;

Unix shell中的命令,以获取“之后的第二个数值”-&引用;,unix,Unix,范例 我需要值8080。所以基本上我们需要在第二次出现'-'之后的数字值 我们尝试了以下选项: prod2-03_dl-httpd-prod-8080_access_referer_log.20181111-050000 无需求助于sed,BASH支持正则表达式: echo "prod2-03_dl-httpd-prod-8080_access_referer_log.20181111-050000" | sed -r 's/([^-][:digit:]+[^-][:digit:]).*/\1

范例

我需要值
8080
。所以基本上我们需要在第二次出现
'-'
之后的数字值

我们尝试了以下选项:

prod2-03_dl-httpd-prod-8080_access_referer_log.20181111-050000

无需求助于
sed
,BASH支持正则表达式:

echo "prod2-03_dl-httpd-prod-8080_access_referer_log.20181111-050000" | sed -r 's/([^-][:digit:]+[^-][:digit:]).*/\1/'
试试这个Perl解决方案

$ A=prod2-03_dl-httpd-prod-8080_access_referer_log.20181111-050000
$ [[ $A =~ ([^-]*-){2}[^[:digit:]]+([[:digit:]]+) ]] && echo "${BASH_REMATCH[2]}"
8080

您可以在POSIX shell中使用IFS来识别部件,并使用循环来逐步找到您要查找的模式:

$ echo "$data" | perl -ne ' /.+?\-(\d+).+?\-(\d+).*/g and print $2 '
8080
请注意,对于看起来像
aa-bb-123cc45-foo
的字符串,这可能会失败。如果在“有趣”字段中可能有其他数字字符串,则需要更多代码

如果您有一个可用的
bash
shell,那么可以通过一系列bash参数扩展来实现这一点

s="prod2-03_dl-httpd-prod-8080_access_referer_log.20181111-050000"

# Set a field separator
IFS=-

# Expand your variable into positional parameters
set - $s

# Drop the first two fields
shift 2

# Drop additional fields until one that starts with a digit
while ! expr "$1" : '[0-9]' >/dev/null; do shift; done

# Capture the part of the string that is not digits
y="$1"; while expr "$y" : '[0-9]' >/dev/null; do y="${y##[[:digit:]]}"; done

# Strip off the non-digit part from the original field
x="${1%$y}"
这与POSIX不兼容,因为如果要求
extglob

当然,bash为您提供了许多选择。考虑这个函数:

# Strip off the first two "fields"
x="${s#*-}"; x="${x#*-}"
shopt -s extglob
x="${x##+([^[:digit:]])}"

# Identify the part on the right that needs to be stripped
y="${x##+([[:digit:]])}"

# And strip it...
x="${x%$y}"
# Strip off the first two "fields"
x="${s#*-}"; x="${x#*-}"
shopt -s extglob
x="${x##+([^[:digit:]])}"

# Identify the part on the right that needs to be stripped
y="${x##+([[:digit:]])}"

# And strip it...
x="${x%$y}"
whatdigits() {
  local IFS=- x i
  local -a a
  a=( $1 )

  for ((i=3; i<${#a[@]}; i++)) {
    [[ ${a[$i]} =~ ^([0-9]+) ]] && echo "${BASH_REMATCH[1]}" && return 0
  }

  return 1
}
$ whatdigits "12-ab-cd-45ef-gh"
45
$ whatdigits "$s"
8080