команда в оболочке, чтобы получить второе числовое значение после "-" - PullRequest
0 голосов
/ 28 ноября 2018

Пример

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

Мне нужно значение 8080.Таким образом, в основном нам нужно цифровое значение после второго появления '-'.

Мы попробовали следующие варианты:

echo "prod2-03_dl-httpd-prod-8080_access_referer_log.20181111-050000" | sed -r 's/([^-][:digit:]+[^-][:digit:]).*/\1/'

Ответы [ 3 ]

0 голосов
/ 28 ноября 2018

Попробуйте это решение Perl

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

$ perl -ne ' /.+?\-(\d+).+?\-(\d+).*/g and print $2 ' <<< "$data"
8080

или

$ echo "$data" | perl -ne ' /.+?\-(\d+).+?\-(\d+).*/g and print $2 '
8080
0 голосов
/ 28 ноября 2018

Вы можете сделать это в оболочке 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
0 голосов
/ 28 ноября 2018

Нет необходимости прибегать к sed, BASH поддерживает регулярные выражения:

$ A=prod2-03_dl-httpd-prod-8080_access_referer_log.20181111-050000
$ [[ $A =~ ([^-]*-){2}[^[:digit:]]+([[:digit:]]+) ]] && echo "${BASH_REMATCH[2]}"
8080
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...