Вы можете сделать это в оболочке POSIX, используя IFS для идентификации деталей и цикл для перехода к искомому шаблону:
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}"
Обратите внимание, что это может не сработать для строки, котораявыглядит как aa-bb-123cc45-foo
.Если у вас могут быть дополнительные строки цифр в «интересном» поле, вам понадобится больше кода.
Если у вас есть доступная оболочка bash
, вы можете сделать это с помощью ряда расширений параметров 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}"
Это несовместимо с POSIX, потому что если требование для extglob
.
Конечно, Bash предлагает вам много вариантов.Рассмотрим эту функцию:
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