J’ai le fichier “acl.txt”
192.168.0.1 192.168.4.5 #start_exceptions 192.168.3.34 192.168.6.78 #end_exceptions 192.168.5.55
et un autre fichier “exceptions”
192.168.88.88 192.168.76.6
Je dois tout remplacer entre #start_exceptions et #end_exceptions avec le contenu du fichier d’exceptions. J’ai essayé beaucoup de solutions de ce forum mais aucune ne fonctionne.
EDITED :
Ok, si vous voulez conserver #start et #stop, je reviens à awk:
awk ' BEGIN {p=1} /^#start/ {print;system("cat exceptions");p=0} /^#end/ {p=1} p' acl.txt
Merci à @fedorqui pour les modifications dans les commentaires ci-dessous.
Sortie:
192.168.0.1 192.168.4.5 #start_exceptions 192.168.88.88 192.168.76.6 #end_exceptions 192.168.5.55
p est un drapeau qui indique s’il faut ou non imprimer des lignes. Il commence au début par 1, donc toutes les lignes sont imprimées jusqu’à ce que je trouve une ligne commençant par #start. Ensuite, je fouille le contenu du fichier d’exceptions et arrête d’imprimer les lignes jusqu’à ce que je trouve une ligne commençant par #end, auquel cas je ramène le drapeau p à 1 pour que les lignes restantes soient imprimées.
Si vous voulez une sortie dans un fichier, ajoutez “> newfile” à la toute fin de la commande comme ceci:
awk ' BEGIN {p=1} /^#start/ {print;system("cat exceptions");p=0} /^#end/ {p=1} p' acl.txt > newfile
ENCORE UNE AUTRE VERSION SI VOUS VOULEZ VRAIMENT UTILISER SED
Si vous voulez vraiment le faire avec sed, vous pouvez utiliser des espaces d’adresse nesteds, tout d’abord pour sélectionner les lignes entre #start_exceptions et #end_exceptions, puis de nouveau pour sélectionner la première ligne et les lignes autres que la ligne #end_exceptions:
sed ' /^#start/,/^#end/{ /^#start/{ n r exceptions } /^#end/!d } ' acl.txt
Sortie:
192.168.0.1 192.168.4.5 #start_exceptions 192.168.88.88 192.168.76.6 #end_exceptions 192.168.5.55
RÉPONSE ORIGINALE
Je pense que cela fonctionnera:
sed -e '/^#end/r exceptions' -e '/^#start/,/^#end/d' acl.txt
Quand il trouve / ^ # end / il lit dans le fichier des exceptions. Et il supprime également tout entre / # start / et / # end /.
J’ai laissé la correspondance légèrement “relâchée” pour clarifier l’expression de la technique.
Vous pouvez utiliser les éléments suivants, basés sur Remplacer la chaîne par le contenu d’un fichier utilisant sed :
$ sed $'/end/ {r exceptions\n} ; /start/,/end/ {d}' acl.txt 192.168.0.1 192.168.4.5 192.168.88.88 192.168.76.6 192.168.5.55
sed $'one_thing; another_thing' ac1.txt
sed $'one_thing; another_thing' ac1.txt
effectue les deux actions. /end/ {r exceptions\n}
si la ligne contient end
, lisez les exceptions
du fichier et ajoutez-la. /start/,/end/ {d}
d’une ligne contenant le start
d’une ligne contenant end
, supprimez toutes les lignes. J’ai eu des problèmes avec la solution de Mark Setchell dans MINGW. Le caret ne relevait pas le début de la ligne. En effet, la détection du séparateur dépend-elle de sa position au début de la ligne? Je suis venu avec cette alternative awk …
$ awk -v data="$(