Comment remplacer une partie d'une ligne par sed?
La ligne
DBSERVERNAME xxx
devrait être remplacé pour:
DBSERVERNAME yyy
La valeur xxx peut varier et il y a deux onglets entre nom_serveur et la valeur. Cette paire nom-valeur est l'une des nombreuses d'un fichier de configuration.
J'ai essayé avec le backreference suivant:
echo "DBSERVERNAME xxx" | sed -rne 's/\(dbservername\)[[:blank:]]+\([[:alpha:]]+\)/\1 yyy/gip'
et cela a entraîné une erreur: référence non valide\1 sur le RHS de la commande `s '.
Quel est le problème avec l'expression? Utiliser GNU sed.
Cela marche:
sed -rne 's/(dbservername)\s+\w+/\1 yyy/gip'
(Lorsque vous utilisez l'option -r, vous n'êtes pas obligé d'échapper aux parenthèses.)
Peu d'explication:
-r
est une expression régulière étendue - fait une différence dans la façon dont l'expression régulière est écrite.-n
n'imprime que si spécifié - sed
imprime par défaut sinon,-e
signifie que ce qui suit est une expression. Décomposons l'expression: s///
est la commande pour search-replace, et ce qui se trouve entre la première paire est la regex à comparer, et la seconde paire, le remplacement,gip
, qui suit la commande search replace; g
signifie global, c’est-à-dire que chaque match au lieu du premier sera remplacé dans une ligne; i
est insensible à la casse; p
signifie imprimer lorsque vous avez terminé (rappelez-vous du drapeau -n
de plus tôt!),dbservername
est la première partie du match,\s
est un espace, +
signifie une ou plusieurs occurrences (vs *
, zéro ou plus),\w
est un mot, c'est-à-dire une lettre, un chiffre ou un trait de soulignement,\1
est une expression spéciale pour GNU sed
qui affiche la première correspondance entre crochets dans la recherche associée.D'autres ont déjà mentionné l'échappement de parenthèses, mais pourquoi avez-vous besoin d'une référence arrière, si la première partie de la ligne est constante?
Vous pourriez simplement faire
sed -e 's/dbservername.*$/dbservername yyy/g'
Vous échappez à votre (et). Je suis sûr que tu n'as pas besoin de faire ça. Essayer:
sed -rne's/(dbservername) [[: blank:]] +\([[: alpha:]] + \)/\ 1 yyy/gip '
Vous ne devriez pas échapper aux choses lorsque vous utilisez des guillemets simples. c'est à dire.
echo "DBSERVERNAME xxx" | sed -rne 's/(dbservername[[:blank:]]+)([[:alpha:]]+)/\1 yyy/gip'
Tu ne devrais pas échapper à tes parents. Essayer:
echo "DBSERVERNAME xxx" | sed -rne 's/(dbservername)[[:blank:]]+([[:alpha:]]+)/\1 yyy/gip'
Cela pourrait fonctionner pour vous:
echo "DBSERVERNAME xxx" | sed 's/\S*$/yyy/'
DBSERVERNAME yyy