web-dev-qa-db-fra.com

Comment remplacer le caractère de substitution ou le mot dans variable par la valeur d'une autre variable dans Bash?

J'essaie d'écrire un script Bash simple. J'ai une simple variable "template":

template = "my*appserver"

J'ai ensuite une fonction (get_env()) qui renvoie les valeurs dev, qa ou live. J'aimerais appeler get_env, puis remplacer par chaîne la variable template par la valeur de retour de get_env et l'échanger avec l'astérisque. Alors:

# Returns "dev"
server = get_env

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

Ou:

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

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

Que devrais-je utiliser à la place de cette fonction string_replace() pour effectuer la liaison? 

29
IAmYourFaja

Bash peut effectuer le remplacement de chaîne par lui-même:

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

Voir le guide de script avancé bash pour plus de détails sur le remplacement de chaîne.

Donc pour une fonction bash:

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

Et à utiliser:

template=$(string_replace "$template" "$server")
58
Spencer Rathbun

Le remplacement de chaîne dans un script bash peut par exemple être atteint par sed:

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

Ceci remplacera old_string par new_string dans la variable de modèle.

36
sge

Comme personne n'en a parlé, voici une possibilité intéressante en utilisant printf. L'emplacement réservé doit cependant être %s et non *.

# 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"

Terminé!

Si vous voulez qu'une fonction le fasse (et remarquez que toutes les autres solutions mentionnant une fonction utilisent un sous-shell moche):

#!/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"

Fait (encore)!

J'espère que vous avez apprécié ... maintenant, adaptez-le à vos besoins!

Remarque. Il semble que cette méthode utilisant printf est légèrement plus rapide que la substitution de chaîne de bash. Et il n'y a pas de sous-coque du tout ici! Wow, c'est la meilleure méthode en Occident.

Marrant. Si vous aimez les choses amusantes, vous pouvez écrire la fonction string_replace ci-dessus en tant que

string_replace() {
    printf -v "$@"
}

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

Ouais, soit "sed" comme le disent les autres, ou commencez avec votre modèle en 2 variables distinctes et construisez à la volée. par exemple.

templateprefix="my"
templatesuffix="appserver"

server=get_env

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

Sur la base de la réponse @Spencer Rathbun, ceci peut également être effectué de la manière suivante:

   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")
1
iarroyo

Il y a tellement de publications disponibles en ligne, mais celle qui a bien fonctionné pour moi est la suivante.

Il y a 2 façons d'y parvenir, si vous voulez remplacer une chaîne (mon ancienne chaîne est avec un caractère spécial :) par une autre chaîne dans un fichier, utilisez ceci:

sed -i '/oldtext:/c\newtext: Rahul'  ./printName.txt

Deuxièmement, si vous souhaitez rechercher une chaîne et la remplacer par votre variable, procédez comme suit:

#here im concatinating two key + value(myvariable).
firstkey="oldtext: old"

key="newtext: "

value=$(cat ./variableStoredHere.txt)

key+=$value

le résultat pour under command sera oldtext: old

echo $firstkey 

résultat pour la commande ci-dessous sera sera newtext: Rahul 

echo $key 


sed -i "s/$firstkey/$key/g" ./printName.txt  
0
Rahul k

Voici un script bash qui résume tout cela

Exemple:

$ 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"
0
Brad Parks

Je devais faire quelque chose comme ça, mais j'avais besoin de sed et la clause de remplacement devait inclure une variable. J'ai fini avec ça.

Où le nom de la variable est $ puttyline

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

Ainsi, sed recherche [remote "Origin"] et se souvient de la correspondance et insère une ligne juste après, contenant tout ce qui se trouve dans la variable $puttyline.

Cela peut devenir moche cependant si $ puttyline contient des caractères spéciaux qui réagiraient à sed, comme\ou $. Vous devez soit leur échapper avant avec un autre appel à sed, soit ... faire quelque chose de plus intelligent dans bash que je suis trop mal pour le savoir. Par exemple, pour doubler toutes les barres obliques inverses:

sed 's/\\/\\\\/g'
0
Chris Moschini