web-dev-qa-db-fra.com

sed remplace le texte contenant la nouvelle ligne

J'ai un script bash pour installer un serveur Web sur mon serveur Ubuntu.

Je voudrais, dans /etc/Apache2/Apache2.conf, remplacer

#ServerRoot "/etc/Apache2"

#

par

#ServerRoot "/etc/Apache2"
ServerName localhost

#

Si je fais

sed -i 's|#ServerRoot "/etc/Apache2"|#ServerRoot "/etc/Apache2"\nServerName localhost|' /etc/Apache2/Apache2.conf

cela fonctionne, mais j'aimerais inclure la ligne vide et le # après le #ServerRoot pour éviter d'ajouter deux fois ServerName si le script est exécuté deux fois.

J'ai essayé

sed -i 's|#ServerRoot "/etc/Apache2"\n\n#|#ServerRoot "/etc/Apache2"\nServerName localhost\n\n#|' /etc/Apache2/Apache2.conf

Mais ça ne marche pas.

3
tweetysat

Que diriez-vous

  1. rechercher #ServerRoot "/etc/Apache2"
  2. si trouvé, lit et ajoute la ligne suivante dans l'espace modèle de sed
  3. recherchez une ligne vide dans l'espace de modèle ajouté après la nouvelle ligne et remplacez ServerName localhost par that

Mettre cela ensemble,

sed -i '\|#ServerRoot "/etc/Apache2"| {N;s|\n$|\nServerName localhost|}' /etc/Apache2/Apache2.conf

Au cas où la ligne "vide" contient réellement des espaces, vous pouvez le modifier en

sed -i '\|#ServerRoot "/etc/Apache2"| {N;s|\n\s*$|\nServerName localhost|}' /etc/Apache2/Apache2.conf
2
steeldriver

Enfin, la double -\n vérification fonctionne dans sed avec aide à partir de ceci . Peu d'une bouchée:

sed -Ei ':a;N;$!ba;s/^(#ServerRoot[^\n]*)\n\n/\1\nServerName localhost\n\n/' Apache2.conf

Et un awk qui fait la même chose (plus long mais plus facile à comprendre à l’OMI). La logique et sponge sont expliqués dans la dernière section.

awk '{print}/^#ServerRoot/{getline; if($0=="") print "ServerName localhost"; print}' Apache2.conf | sponge Apache2.conf

Edit: La sed n'est pas aussi dure que je le pensais. Vous voulez juste faire correspondre et ajouter (la commande a); vous n'avez pas besoin de remplacer. J'ai testé le fonctionnement suivant:

sed -i '/^#ServerRoot/a ServerName localhost' Apache2.conf

Vous pouvez être plus précis avec votre match si vous le souhaitez et je laisserai la awk ci-dessous pour la postérité.


La modification est assez simple avec awk, mais pour pouvoir écrire dans le même fichier, nous avons besoin d’un fichier intermédiaire temporaire ou de sponge (du paquet moreutils). Je vais montrer les deux méthodes.

awk '{print}/^#ServerRoot/{print "ServerName localhost"}' Apache2.conf > tmp
mv tmp Apache2.conf

Ou

awk '{print}/^#ServerRoot/{print "ServerName localhost"}' Apache2.conf | sponge Apache2.conf

La awk imprime simplement chaque ligne trouvée, mais dans le cas d'une correspondance pour ^#ServerName, votre ligne ServerName est alors écrite. Je trouve ce type de traitement beaucoup plus facile à lire qu'un "échange" arbitraire avec sed.

0
Oli

Une autre façon (merci muru) mais un peu hors contexte car ne pas utiliser sed:

Pour buntu 14.04:

Créez un fichier fqdn.conf dans / etc/Apache2/conf-available / contenant

ServerName localhost

Créez un lien symbolique dans/etc/Apache2/conf-enabled /

Sudo ln -s /etc/Apache2/conf-available/fqdn.conf /etc/Apache2/conf-enabled/fqdn.conf
0
tweetysat