web-dev-qa-db-fra.com

Comment ajouter une ligne de texte au milieu d'un fichier à l'aide de bash?

J'essaie d'ajouter une ligne de texte au milieu d'un fichier texte dans un script bash. Plus précisément, j'essaie d'ajouter un serveur de noms à mon fichier /etc/resolv.conf. En l'état actuel, resolv.conf ressemble à ceci:

# Generated by NetworkManager
domain dhcp.example.com
search dhcp.example.com
nameserver 10.0.0.1
nameserver 10.0.0.2
nameserver 10.0.0.3

Mon objectif est d’ajouter nameserver 127.0.0.1 au-dessus de toutes les autres lignes du serveur de noms, mais en dessous du texte au-dessus. En fin de compte, je veux que mon fichier resol.conf ressemble à ceci:

# Generated by NetworkManager
domain dhcp.example.com
search dhcp.example.com
nameserver 127.0.0.1
nameserver 10.0.0.1
nameserver 10.0.0.2
nameserver 10.0.0.3

Comment cela est-il possible via un script bash? Est-ce que c'est quelque chose que sed ou awk peut faire? Ou est-ce que la meilleure façon de créer le fichier créatif serait de faire un greping créatif?

35
PHLAK

Voici une solution utilisant sed:

$ sed -n 'H;${x;s/^\n//;s/nameserver .*$/nameserver 127.0.0.1\n&/;p;}' resolv.conf

# Generated by NetworkManager
domain dhcp.example.com
search dhcp.example.com
nameserver 127.0.0.1
nameserver 10.0.0.1
nameserver 10.0.0.2
nameserver 10.0.0.3

Comment ça marche: premièrement, supprimez la sortie de sed avec le drapeau -n. Ensuite, pour chaque ligne, nous ajoutons la ligne à l'espace réservé, en les séparant par des lignes:

H

Lorsque nous arrivons à la fin du fichier (adressé par $), nous déplaçons le contenu de l'espace de stockage vers l'espace de modèle:

x

Si la première ligne de l'espace de modèle est vide, nous la remplaçons par rien.

s/^\n//

Ensuite, nous remplaçons la première ligne commençant par nameserver par une ligne contenant nameserver 127.0.0.1, une nouvelle ligne (votre version de sed peut ne pas prendre en charge \n, auquel cas remplacer la n par une nouvelle ligne littérale) et la ligne d'origine (représentée par &):

s/nameserver .*$/nameserver 127.0.0.1\n&/

Il ne reste plus qu'à imprimer les résultats:

p
39
brandizzi

En supposant que vous vouliez insérer immédiatement après la ligne search, ceci est beaucoup plus simple:

sed -ie '/^search/a nameserver 127.0.0.1' filename
  • -i: éditer le fichier en place
  • -e: permet l'exécution d'un script/de commandes dans une expression sed
  • a mynewtext: commande qui indique à sed d'insérer le texte mynewtext après le motif correspondant
19
Jim Garrison

awk '/^nameserver/ && !modif { printf("INSERT\n"); modif=1 } {print}'

8
Karoly Horvath

Que diriez-vous de quelque chose comme:

sed -e ':a;N;$!ba;s/nameserver/nameserver 127.0.0.1\nnameserver/' /etc/resolv.conf

(semblable à ceci: sed: recherche d'un motif sur deux lignes, ne pas remplacer après ce motif )

2
sagi

Cela pourrait fonctionner pour vous:

 sed -e '/nameserver/{x;/./b;x;h;i\nameserver 127.0.0.1' -e '}' resolv.conf

Ou GNU sed:

sed -e '0,/nameserver/{//i\nameserver 127.0.0.1' -e '}' resolv.conf
0
potong