2017-01-27 1 views
1

Je suis en train de remplacer certaines lignes dans/etc/hosts avec mon script ici:bash obtenu après des sauts de ligne indésirables sed et le chat >>

#!/bin/bash 

hosts_file_path="/etc/hosts" 

nas_servers=('mynas01' 'mynas02') 

strange_string="<00>" 

for nas_name in ${nas_servers[@]}; do 
    printf '%ls\n' "$nas_name" 
    r="$(nmblookup "$nas_name")" 
    if [[ ! -z "$r" ]] && [[ "$r" != "name_query" ]]; then 
     l=${#r} 
     ls=${#strange_string} 
     cl=$(($l-$ls)) 
     echo "$cl" 
     s="${r:0:cl}" 
     printf '"%ls"\n' "$s" 
     res="$(grep -i "$nas_name" "$hosts_file_path")" 
     echo "$res" 
     if [ ! -z "$res" ]; then 
      sr="s/.*${nas_name}.*//g" 
      echo "$sr" 
      sed -i "$sr" "$hosts_file_path" 
     fi 
     printf '%ls\n' "$s" >> "$hosts_file_path" 
    fi 
done 

Il recherche par exemple pour les lignes comme

192.168.1xx.xxx mynas01 

et remplace la ligne (si elle a trouvé) avec une commande sed à rien, mais ajoute par la suite par exemple à

192.169.1xx.xxx mynas01 

Je vais avoir à faire cela parce que mes adresses réseau LAN changent très souvent (exactement: à chaque journée de travail, mais pas toujours dans une séance de travail) (?), l'édition et chaque fois que le fichier/etc Le fichier/hosts n'est pas très utile, même pour configurer des choses comme SNMP (pour deux serveurs) un peu trop de temps pour moi - je veux juste mettre ce script dans un job cron ou dans rc.local et éviter les smockups.

Maintenant ma question (s): Si je le fais de cette façon, il y aura plus de nouvelles lignes vides après la fin du fichier et/entre le texte ajouté, Comment puis-je éviter cela et y at-il un moyen plus court ?

Jusqu'à présent, je suis arrivé à la suite (/ etc/hosts):

127.0.0.1  localhost 
127.0.1.1  hostname.fqdn.example.com hostnam 

(^ the space here got more and more by each call of my script, more newlines and more newlines) 


192.168.1xx.101 mynas01 
192.168.1xx.102 mynas02 

Merci

Répondre

1

Le problème est que votre commande sed, au lieu de en supprimant la ligne de intérêt, le transforme en ligne vide, donc en effet vous vide une ancienne entrée NAS tout en ajoutant une nouvelle ligne pour elle, qui continue d'ajouter des lignes.

Utilisez la commande sed suivante à la place, qui supprime la ligne correspondante:

sr="/${nas_name}/ d" 

ou, plus robuste, pour écarter les faux positifs:

sr="/[[:blank:]]${nas_name}[[:blank:]]*$/ d" 

Depuis un double- cité chaîne est utilisée, vous devez généralement utiliser \$ pour $ caractères. que le shell devrait pas se dilater.
Cependant, le shell laisse quelque chose qui n'est pas une référence de variable syntaxiquement valide seul, donc $/ est passé à sed tel quel.
Pour une séparation plus stricte de la partie développée de l'interpréteur de commandes (double guillemet) et du script Sed (guillemets simples), vous pouvez utiliser ce qui suit, mais qui est plus difficile à lire: sr='/[[:blank:]]'"${nas_name}"'[[:blank:]]*$/ d'. Généralement, cependant, c'est une approche valable.

Notez que votre script pourrait être simplifié à bien des égards, y compris en utilisant une seule commande sed de mettre à jour l'entrée existante directement au lieu de supprimer l'ancienne entrée avec sed d'abord, puis l'ajout d'un nouveau avec cat.

1

Il suffit d'utiliser grep -v pour supprimer les lignes que vous n'aimez pas du dossier. C'est beaucoup plus facile que sed après grep comme vous avez maintenant, et il ne vous laissera pas avec des lignes vides.

+0

Mais grep -v renvoie la recherche inversée pour une correspondance grep. Comment puis-je le faire pour deux ou plusieurs chaînes (mynas01, mynas02, mynas03 ...)? –

+2

'grep -v' est peut-être un peu plus facile, mais si vous voulez aussi une mise à jour sur place du fichier d'entrée (comme c'est le cas ici),' sed -i' est pratique, et le seul problème de l'OP 'Fonction pour remplacer une ligne correspondante par une chaîne _empty_ au lieu d'utiliser la fonction' d' pour le supprimer. – mklement0

+0

@aprogrammer: 'egrep -v 'mynas [0-9] +'' est un moyen. –

-1

En supposant que vous avez un fichier/etc/hosts qui ressemble à ceci

192.168.111.000 mynas01 
192.168.222.000 mynas01 
192.168.333.000 mynas01 
000.192.168.000 mynas01 

vous devez juste faire:

cat /etc/hosts | sed 's/^192\.168\./192\.169\./' 

et vous obtenez

192.169.111.000 mynas01 
192.169.222.000 mynas01 
192.169.333.000 mynas01 
000.192.168.000 mynas01 
+0

Comme vous le voyez, il y a une liste de chaînes (ou mieux: une liste de noms de mon NAS, que je veux changer: mynas01, ...) –

+0

A quoi ressemble le fichier original/etc/hosts? – Manolo

+0

Il n'est pas clair comment votre réponse se rapporte à la question. – mklement0