Как заменить символ-заполнитель или слово в переменной значением из другой переменной в Bash?

Я пытаюсь написать простой Bash script. У меня есть простая переменная "шаблон":

template = "my*appserver"

Затем у меня есть функция (get_env()), которая возвращает значения dev, qa или live. Я бы назвал get_env, а затем заменил строку template переменной get_env возвращаемым значением и заменил ее звездочкой. Итак:

# Returns "dev"
server = get_env

# Prints "mydevappserver"
template = string_replace(server, template)

Или:

# This time, it returns "live"
server = get_env

# Prints "myliveappserver"
template = string_replace(server, template)

Что я должен использовать вместо этой функции string_replace() для выполнения привязки?

Ответ 1

Bash может выполнять замену строки самостоятельно:

template='my*appserver'
server='live'
template="${template/\*/$server}"

Подробнее о замене строк см. в расширенном bash руководстве по сценариям.

Итак, для функции bash:

function string_replace {
    echo "${1/\*/$2}"
}

И использовать:

template=$(string_replace "$template" "$server")

Ответ 2

Замена строк в bash - script может, например, достигается sed:

template=$(echo $template | sed 's/old_string/new_string/g')

Это заменит old_string на new_string в переменной шаблона.

Ответ 3

Как никто не упомянул об этом, здесь крутая возможность с использованием printf. Держатель места должен быть %s, но не *.

# use %s as the place-holder
template="my%sappserver"

# replace the place-holder by 'whatever-you-like':
server="whatever-you-like"
printf -v template "$template" "$server"

Готово!

Если вы хотите, чтобы функция выполняла это (и заметила, как все остальные решения, упоминающие функцию, используют уродливую подоболочку):

#!/bin/bash

# This wonderful function should be called thus:
# string_replace "replacement string" "$placeholder_string" variable_name
string_replace() {
    printf -v $3 "$2" "$1"
}

# How to use it:
template="my%sappserver"
server="whatever-you-like"

string_replace "$server" "$template" destination_variable

echo "$destination_variable"

Готово (снова)!

Надеюсь, вам понравилось... теперь приспособите его к вашим потребностям!

Примечание. Кажется, что этот метод с использованием printf немного быстрее, чем bash замена строки. И здесь вообще нет подоболочки! Вау, это лучший метод на Западе.

Забавно. Если вам нравятся смешные вещи, вы можете написать функцию string_replace выше как

string_replace() {
    printf -v "[email protected]"
}

# but then, use as:
string_replace destination_variable "$template" "$server"

Ответ 4

Да, или "sed", как говорили другие, или начните с вашего шаблона в 2 отдельных переменных и постройте "на лету". например.

templateprefix="my"
templatesuffix="appserver"

server=get_env

template=${templateprefix}${server}${templatesuffix}

Ответ 5

На основе ответа @Spencer Rathbun это также можно сделать следующим образом:

   function string_replace {
        #DOC: "${string/match/replace}"
        string=$1
        echo "${string/$2/$3}"
    }

    template='my__patternReplacing__appserver'
    match='__patternReplacing__'
    replace='live'

    template=$(string_replace "$template" "$match" "$replace")

Ответ 6

Мне нужно было сделать что-то подобное, но мне понадобилось sed и предложение replace, чтобы включить переменную. Я закончил с этим.

Если имя переменной $puttyline

sed "s/\(\[remote .origin.\]\)/\1\n$puttyline/"

Итак, sed ищет [remote "origin"] и запоминает совпадение, и вставляет строку сразу после, содержащую что-то в переменной $puttyline.

Это может быть уродливым, но если $puttyline содержит любые специальные символы, на которые sed отреагировал бы, например\или $. Вы должны либо сбежать от них до другого вызова sed, либо... сделать что-то умнее в bash, что я слишком дерьмова с bash, чтобы знать. Например, чтобы дважды избежать всех обратных косых черт:

sed 's/\\/\\\\/g'

Ответ 7

Здесь bash script, который обертывает это

Пример:

$ search_and_replace.sh "test me out" "test me" ez
ez out

search_and_replace.sh

#!/bin/bash
function show_help()
{
  echo ""
  echo "usage: SUBJECT SEARCH_FOR REPLACE_WITH"
  echo ""
  echo "e.g. "
  echo ""
  echo "test t a                     => aesa"
  echo "'test me out' 'test me' ez   => ez out"
  echo ""

  exit
}

if [ "$1" == "help" ]
then
  show_help
  exit
fi
if [ -z "$3" ]
then
  show_help
  exit
fi

SUBJECT=$1
SEARCH_FOR=$2
REPLACE_WITH=$3

echo "$SUBJECT" | sed -e "s/$SEARCH_FOR/$REPLACE_WITH/g"