Ответ 1
$ foo=${string#"$prefix"}
$ foo=${foo%"$suffix"}
$ echo "${foo}"
o-wor
В моем bash
script у меня есть строка и ее префикс/суффикс. Мне нужно удалить префикс/суффикс из исходной строки.
Например, допустим, что у меня есть следующие значения:
string="hello-world"
prefix="hell"
suffix="ld"
Как мне получить следующий результат?
result="o-wor"
$ foo=${string#"$prefix"}
$ foo=${foo%"$suffix"}
$ echo "${foo}"
o-wor
Использование sed:
$ echo "$string" | sed -e "s/^$prefix//" -e "s/$suffix$//"
o-wor
В команде sed символ ^
соответствует тексту, начинающемуся с $prefix
, а завершающий $
соответствует тексту, заканчивающемуся на $suffix
.
Адриан Фрюхвирт делает несколько замечательных замечаний в комментариях ниже, но sed
для этой цели может быть очень полезен. Тот факт, что содержимое префикса $и $суффикса интерпретируется sed, может быть либо хорошим, либо плохим - пока вы обращаете внимание, вы должны быть в порядке. Красота такова, вы можете сделать что-то вроде этого:
$ prefix='^.*ll'
$ suffix='ld$'
$ echo "$string" | sed -e "s/^$prefix//" -e "s/$suffix$//"
o-wor
который может быть тем, что вы хотите, и является более привлекательным и мощным, чем замена переменной bash. Если вы помните, что с великой силой приходит большая ответственность (как говорит Спайдерман), вы должны быть в порядке.
Краткое введение в sed можно найти на http://evc-cit.info/cit052/sed_tutorial.html
Замечание относительно оболочки и ее использование строк:
В приведенном конкретном примере также будет работать следующее:
$ echo $string | sed -e s/^$prefix// -e s/$suffix$//
... но только потому, что:
Как правило, правильная практика цитирует строку в командной строке, потому что даже если она содержит пробелы, она будет представлена команде как один аргумент. Мы приводим $prefix и $suffix по той же причине: каждая команда редактирования sed будет передана как одна строка. Мы используем двойные кавычки, потому что они допускают переменную интерполяцию; если бы мы использовали одинарные кавычки, команда sed получила бы буквальный $prefix
и $suffix
, который, конечно же, не тот, который мы хотели.
Также обратите внимание, что использование одиночных кавычек при настройке переменных prefix
и suffix
. Мы, конечно, не хотим, чтобы что-то в строках интерпретировалось, поэтому мы приводим их отдельно, поэтому интерполяция не происходит. Опять же, это может быть не нужно в этом примере, но это очень хорошая привычка вступать.
Знаете ли вы длину вашего префикса и суффикса? В твоем случае:
result=$(echo $string | cut -c5- | rev | cut -c3- | rev)
Или более общий:
result=$(echo $string | cut -c$((${#prefix}+1))- | rev | cut -c$((${#suffix}+1))- | rev)
Но решение от Adrian Frühwirth - это круто! Я не знал об этом!
Я использую grep для удаления префиксов из путей (которые не обрабатываются с помощью sed
):
echo "$input" | grep -oP "^$prefix\K.*"
\K
удаляет из совпадения все символы перед ним.
$ string="hello-world"
$ prefix="hell"
$ suffix="ld"
$ #remove "hell" from "hello-world" if "hell" is found at the beginning.
$ prefix_removed_string=${string/#$prefix}
$ #remove "ld" from "o-world" if "ld" is found at the end.
$ suffix_removed_String=${prefix_removed_string/%$suffix}
$ echo $suffix_removed_String
o-wor
ПрефикС# $: добавление # гарантирует, что подстрока "ад" удаляется, только если она найдена в начале. % $ suffix: добавление% гарантирует, что подстрока "ld" удаляется, только если она найдена в конце.
Без них подстроки "ад" и "ld" будут удалены повсюду, даже если они будут найдены посередине.
Малое и универсальное решение:
expr "$string" : "$prefix\(.*\)$suffix"
Использование оператора =~
:
$ string="hello-world"
$ prefix="hell"
$ suffix="ld"
$ [[ "$string" =~ ^$prefix(.*)$suffix$ ]] && echo "${BASH_REMATCH[1]}"
o-wor
Используя @Adrian Frühwirth ответ:
function strip {
local STRING=${1#$"$2"}
echo ${STRING%$"$2"}
}
используйте его так
HELLO=":hello:"
HELLO=$(strip "$HELLO" ":")
echo $HELLO # hello
Я хотел бы использовать группы захвата в регулярном выражении:
$ string="hello-world"
$ prefix="hell"
$ suffix="ld"
$ set +H # Disables history substitution, can be omitted in scripts.
$ perl -pe "s/${prefix}((?:(?!(${suffix})).)*)${suffix}/\1/" <<< $string
o-wor
$ string1=$string$string
$ perl -pe "s/${prefix}((?:(?!(${suffix})).)*)${suffix}/\1/g" <<< $string1
o-woro-wor
((?:(?!(${suffix})).)*)
гарантирует, что содержимое ${suffix}
будет исключено из группы захвата. В качестве примера, это строка, эквивалентная [^A-Z]*
. В противном случае вы получите:
$ perl -pe "s/${prefix}(.*)${suffix}/\1/g" <<< $string1
o-worldhello-wor