2009-07-02 10 views
32

Comment remplacer une partie d'une ligne par sed?sed: Remplacer une partie d'une ligne

La ligne

DBSERVERNAME  xxx 

doit être remplacé à:

DBSERVERNAME  yyy 

La valeur xxx peut varier et il y a deux pattes entre dbServerName et la valeur. Cette paire nom-valeur est l'une des nombreuses d'un fichier de configuration.

J'ai essayé avec la backreference suivante:

echo "DBSERVERNAME xxx" | sed -rne 's/\(dbservername\)[[:blank:]]+\([[:alpha:]]+\)/\1 yyy/gip' 

et qui a abouti à une erreur: référence non valide \ 1 sur RHS de la commande `s.

Quel est le problème avec l'expression? Utiliser GNU sed.

Répondre

39

Cela fonctionne:

sed -rne 's/(dbservername)\s+\w+/\1 yyy/gip' 

(Lorsque vous utilisez l'option -r, vous ne devez pas échapper aux parens.)

+2

Je sais que vous avez beaucoup d'expérience dans les commandes shell ... mais s'il vous plait prenez soin des aspirants linux noobs dans la mesure du possible .... tout ce qui est dans '' '' 'doit être expliqué ... ou je dois parcourir l'ensemble [doc] (https://www.gnu.org/software/sed/manual/sed.html) – Mahesha999

2

Vous échappez votre (et). Je suis sûr que vous n'avez pas besoin de faire ça. Essayez:

 
sed -rne 's/(dbservername)[[:blank:]]+\([[:alpha:]]+\)/\1 yyy/gip' 
1

Vous ne devriez pas échapper à des choses lorsque vous utilisez des guillemets simples. c'est à dire.

echo "DBSERVERNAME xxx" | sed -rne 's/(dbservername[[:blank:]]+)([[:alpha:]]+)/\1 yyy/gip' 
1

Vous ne devriez pas échapper à vos parens. Essayez:

echo "DBSERVERNAME xxx" | sed -rne 's/(dbservername)[[:blank:]]+([[:alpha:]]+)/\1 yyy/gip' 
7

D'autres ont déjà mentionné l'Évasion de parenthèses, mais pourquoi avez-vous besoin d'une référence arrière du tout, si la première partie de la ligne est constante?

Vous pouvez simplement faire

sed -e 's/dbservername.*$/dbservername yyy/g' 
+1

Bon point! Je venais d'apprendre à utiliser regexps + sed et mind juste décidé 'regexp' en voyant cette tâche particulière, puis comme 'jwz' dit 'j'ai eu deux problèmes' (mais pas directement à cause des regexps) :) – calvinkrishy

+0

Ceci obtient mon vote parce que c'est la solution la plus simple à un problème simple. L'utilisation d'une référence arrière vous éviterait de tromper les deux copies de 'dbservername'. C'est évident ici, mais quand je modifie postgresql.conf dans sed je trouve difficile de voir d'un coup d'oeil si j'ai tapé 'listen_address' ou' listen_addresses' (postgresql.conf).Les deux semblent plausibles, mais un seul est correct. –

1

Cela pourrait fonctionner pour vous:

echo "DBSERVERNAME  xxx" | sed 's/\S*$/yyy/' 
DBSERVERNAME  yyy 
0

Essayez cette

sed -re 's/DBSERVERNAME[ \t]*([^\S]+)/\yyy/ig' temp.txt

ou cette

awk '{if($1=="DBSERVERNAME") $2 ="YYY"} {print $0;}' temp.txt

Questions connexes