3
votes

Comment insérer des lignes après le deuxième motif avec la commande Linux sed

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


2 commentaires

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é et sed -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 commander r 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


3 Réponses :


1
votes

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 ...


1 commentaires

Je dois créer un fichier script qui le fasse automatiquement, c'est pourquoi j'utilise sed



2
votes

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
  • Il aspire d'abord toutes les lignes pour traiter efficacement plusieurs lignes.
  • Il suppose que l'accolade droite } 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.


4 commentaires

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.



1
votes

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


0 commentaires