Je veux insérer ce bloc:
subnet 10.10.0.0 netmask 255.255.255.0 { range 10.10.0.2 10.10.0.254; group { filename "10M-5M-OKS2016NOV.cm"; host client1 { hardware ethernet a0:b4:3d:bc:df:fa; } host client2 { hardware ethernet 90:6e:bb:ba:cd:d4; } } } subnet 11.10.0.0 netmask 255.255.255.0 { range 11.10.1.2 11.10.1.254; group { filename "10M-5M-OKS2016NOV.cm"; host client1 { hardware ethernet c0:14:e3:bc:df:fa; } host client2 { hardware ethernet 90:6e:fb:ba:3d:04; } } } subnet 12.10.0.0 netmask 255.255.255.0 { range 12.10.2.2 12.10.2.254; group { filename "10M-5M-OKS2016NOV.cm"; host client1 { hardware ethernet c0:a4:3d:bc:df:fa; } host client2 { hardware ethernet 90:6e:bb:ca:3d:04; } } }
après ce bloc:
sed -n -e :a -e '/subnet 11\.10\.0\.0 netmask 255\.255\.255\.0/,/}/{/filename "10M-5M-OKS2016NOV\.cm";/!{$!{N;ba};};a\ \thost client3 {\n\thardware ethernet c0:03:03:bc:30:fa;\n\t}\n;}' dhcpd.conf
La ligne: filename "10M- 5M-OKS2016NOV.cm ";
apparaît plusieurs fois dans le fichier. Mais une seule fois dans le sous-réseau 11.10.0.0 masque de réseau 255.255.255.0 {
Jusqu'à présent, je peux imprimer le bloc de sous-réseau jusqu'au "nom de fichier":
sed -n -e :a -e '/subnet 11\.10\.0\.0 netmask 255\.255\.255\.0/,/}/{/filename "10M-5M-OKS2016NOV\.cm";/!{$!{N;ba};};p;}' dhcpd.conf
3 Réponses :
sed
est excellent comme éditeur de flux, ce qui signifie traiter plusieurs fois les mêmes actions. Ici, vous voulez simplement insérer une fois un bloc de texte. Ce serait beaucoup plus simple (plus lisible et maintenable) avec ed
:
ed dhcpd.conf <<EOF /subnet 11.10.0.0/ /filename/ a host client3 { hardware ethernet c0:03:03:bc:30:fa; } . w q EOF
Attention: ed est un éditeur de fichier . Cela signifie que le fichier dhcpd.conf sera modifié par le script ci-dessus. Assurez-vous d'avoir une sauvegarde en cas de problème ...
Je dois créer un fichier script qui le fasse automatiquement, c'est pourquoi j'utilise sed
Veuillez essayer quelque chose comme:
subnet 10.10.0.0 netmask 255.255.255.0 { range 10.10.0.2 10.10.0.254; group { filename "10M-5M-OKS2016NOV.cm"; host client1 { hardware ethernet a0:b4:3d:bc:df:fa; } host client2 { hardware ethernet 90:6e:bb:ba:cd:d4; } } } subnet 11.10.0.0 netmask 255.255.255.0 { range 11.10.1.2 11.10.1.254; group { filename "10M-5M-OKS2016NOV.cm"; host client3 { hardware ethernet c0:03:03:bc:30:fa; } host client1 { hardware ethernet c0:14:e3:bc:df:fa; } host client2 { hardware ethernet 90:6e:fb:ba:3d:04; } } } subnet 12.10.0.0 netmask 255.255.255.0 { range 12.10.2.2 12.10.2.254; group { filename "10M-5M-OKS2016NOV.cm"; host client1 { hardware ethernet c0:a4:3d:bc:df:fa; } host client2 { hardware ethernet 90:6e:bb:ca:3d:04; } } }
Cela donne la sortie suivante en utilisant les lignes publiées comme dhcpd.conf
,
#!/bin/bash # define newline and tab characters for replacement NL=$'\n' NL="\\$NL" TAB=$'\t' TAB="\\$TAB" sed ' :l N $!b l # first of all slurp all lines in the pattern space # and perform the replacement over the lines s/subnet 11\.10\.0\.0 netmask 255\.255\.255\.0[^}]*filename "10M-5M-OKS2016NOV\.cm";/&'"$NL$TAB"'host client3 {'"$NL$TAB$TAB"'hardware ethernet c0:03:03:bc:30:fa;'"$NL$TAB"'}/g ' dhcpd.conf
}
n'apparaît pas dans le bloc cible de recherche
pour obtenir la correspondance la plus courte en regex. J'espère que cela vous aidera.
Très bonne solution. Que se passe-t-il s'il y a plusieurs «noms de fichiers» et que celui que nous voulons n'est pas le premier. comme: group {filename "30M-5M-OKS2016NOV.cm"; } groupe {nom de fichier "20M-5M-OKS2016NOV.cm"; } groupe {nom de fichier "10M-5M-OKS2016NOV.cm"; }
Laissez-moi confirmer votre exigence. Voulez-vous ajouter le bloc de 3 lignes après l'un des group {filename "30M-5M-OKS2016NOV.cm"; }
, group {nom de fichier "20M-5M-OKS2016NOV.cm"; }
ou group {nom de fichier "10M-5M-OKS2016NOV.cm"; }
?
Insérer après le groupe {nom de fichier "10M-5M-OKS2016NOV.cm"; }
Ma réponse publiée correspond uniquement au groupe {nom de fichier "10M-5M-OKS2016NOV.cm"; }
et répondra à vos besoins tel quel.
Cela pourrait fonctionner pour vous (GNU sed):
cat <<\! | sed '/subnet 11\.10\.0\.0 netmask 255\.255\.255\.0/!b;:a;n;/filename "10M-5M-OKS2016NOV\.cm";/!ba;r /dev/stdin' file host client3 { hardware ethernet c0:03:03:bc:30:fa; } !
Ceci trouve la première ligne contenant subnet 11.10.0.0 netmask 255.255.255.0
et continue à lire jusqu'à la ligne contenant nom de fichier "10M-5M-OKS2016NOV.cm";
. Après avoir imprimé cette ligne, il utilise la ligne comme modèle pour formater le détail requis.
Une autre solution, en utilisant un fichier d'insertion préformé:
sed '/subnet 11\.10\.0\.0 netmask 255\.255\.255\.0/{:a;n;/filename "10M-5M-OKS2016NOV\.cm";/!ba;p;s/\S.*/host client3 {/p;s// hardware ethernet c0:03:03:bc:30:fa;/p;s//}/}' file
Sed
a
pour l'ajout est difficile à intégrer. Vous pourriez probablement obtenir ce que vous voulez en travaillant avec un fichier de commande séparé etsed -f
. Faites de chaque ligne un ajout. Vous pouvez également coller le bloc multiligne que vous souhaitez ajouter dans un fichier séparé et le commanderr
dans le flux de sortie.Je veux juste être sûr que cette ligne:
filename "10M-5M-OKS2016NOV.cm";
est à l'intérieur de ce sous-réseau:subnet 11.10.0.0 netmask 255.255.255.0 {
ou au moins après la ligne thtat