Как сопоставить до последнего появления символа в оболочке bash
Я использую curl
а также cut
на выходе, как показано ниже.
var=$(curl https://avc.com/actuator/info | tr '"' '\n' | grep - | head -n1 | cut -d'-' -f -1, -3)
Varible var
get имеет два вида значений (по одному за раз).
HIX_MAIN-7ae526629f6939f717165c526dad3b7f0819d85b
HIX-R1-1-3b5126629f67892110165c524gbc5d5g1808c9b5
Я на самом деле пытаюсь получить все до последнего "-". т.е. HIX-MAIN
или же HIX-R1-1
,
Показанная команда отлично работает, чтобы получить HIX-R1-1
,
Но я подумал, что это неправильный способ сделать, когда у меня есть что-то вроде только 1 -
в переменной; это дает мне полное значение переменной (например, HIX_MAIN-7ae526629f6939f717165c526dad3b7f0819d85b
).
Как мне получить все до последнего '-' в переменной var
?
4 ответа
Это удаляет все из последнего -
к концу:
sed 's/\(.*\)-.*/\1/'
В качестве примеров:
$ echo HIX_MAIN-7ae52 | sed 's/\(.*\)-.*/\1/'
HIX_MAIN
$ echo HIX-R1-1-3b5126629f67 | sed 's/\(.*\)-.*/\1/'
HIX-R1-1
Как это устроено
Команда sed substitute имеет вид s/old/new/
где old
это регулярное выражение. В этом случае регулярное выражение \(.*\)-.*
, Это работает, потому что \(.*\)-
жаден: он будет соответствовать всему до последнего -
, Из-за сбежавших паренов,\(...\)
все до последнего -
будет сохранен в группе 1, которую мы можем назвать \1
, Финал .*
соответствует всему после последнего -
, Таким образом, пока строка содержит -
это регулярное выражение соответствует всей строке, а команда замены заменяет всю строку \1
,
Вы можете использовать bash для работы со строками:
$ foo=a-b-c-def-ghi
$ echo "${foo%-*}"
a-b-c-def
Операторы, #
а также %
по обе стороны от $
на QWERTY-клавиатуре, которая помогает запомнить, как они изменяют переменную:
#pattern
обрезает самый короткий префикс, соответствующий "шаблону".##pattern
обрезает самый длинный префикс, соответствующий "шаблону".%pattern
обрезает самый короткий суффикс, соответствующий "шаблону".%%pattern
обрезает самый длинный суффикс, соответствующий "шаблону".
где pattern
соответствует правилам сопоставления шаблонов bash, включая ?
(один символ) и *
(ноль или более символов).
Здесь мы обрезаем самый короткий суффикс, соответствующий шаблону -*
, так ${foo%-*}
получите то, что вы хотите.
Конечно, есть много способов сделать это, используя awk
или же sed
возможно повторное использование sed
Команда, которую вы уже выполняете. Однако манипулирование переменными можно выполнять в bash без запуска другого процесса.
Вы можете перевернуть строку с rev
, cut
со второго поля, а затем rev
снова:
rev <<< "$VARIABLE" | cut -d"-" -f2- | rev
За HIX-R1-1----3b5126629f67892110165c524gbc5d5g1808c9b5
, печать:
HIX-R1-1---
Я думаю, что вы должны использовать sed
по крайней мере после tr
:
var=$(curl https://avc.com/actuator/info | tr '"' '\n' | sed -n '/-/{s/-[^-]*$//;p;q}')
-n
означает "не печатать по умолчанию". /-/
ищет строку, содержащую тире; затем выполняется s/-[^-]*$//
удалить последнюю черту и все после нее, а затем p
напечатать и q
выйти (поэтому он печатает только первую такую строку).
Я предполагаю, что выход из curl
по сути, содержит несколько строк, некоторые из которых содержат нежелательные двойные кавычки, и что вам нужно сопоставлять только первую строку, которая содержит тире (которая вполне может быть не первой строкой). После того, как вы урезали ввод до единственной интересной строки, вы можете использовать чистые методы оболочки, чтобы получить желаемый результат, но получение единственной интересной строки не так тривиально, как некоторые из ответов, по-видимому, предполагают.