1
votes

Python - Lire des lignes de texte spécifiques

J'essaye de rechercher des fichiers pour un texte spécifique. Ensuite, imprimez la ligne juste avant la ligne, et toutes les lignes suivantes qui commencent par un caractère spécifique, en particulier un «espace».

Voici un exemple du fichier que j'essaie de lire:

for file in glob.glob('*.log'):
with open(file) as search:
    with open(queryoutput,"a") as foutput:
        for line in search:
            line = line.rstrip()
            if hostcheck in line:
                hostentry = line.split("hostname ")[1]
                foutput.write("Subnet information below is from " + hostentry + "\n")
            elif ipaddress in line:
                foutput.write("Local Device: " + hostentry + "\n")
                foutput.write("Remote " + line + "\n")

Quand je vois "Adresse IP", je veux imprimer la ligne juste avant, puis tous les éléments de configuration sous cette interface.

Actuellement, je lis à partir d'un répertoire des fichiers et la sortie d'informations spécifiques à partir des fichiers. Voici le code:

interface vlan 22
 ip address 10.10.2.1 255.255.255.0
 ip helper-address 10.10.44.1
 ip helper-address 10.10.44.2
!
interface vlan 23
 ip address 10.10.23.1 255.255.255.0
 ip helper-address 10.10.44.1
 ip helper-address 10.10.44.2
!

Tous les périphériques réseau n'indiqueront pas "interface" dans la ligne VLAN, c'est pourquoi je ne veux pas rechercher ce texte, et il n'y en a pas une garantie qu'une exclamation serait le dernier élément, bien que ce soit hautement probable. C'est pourquoi je cherche un moyen de lire les lignes en fonction de l'adresse IP et des espaces.

Je suis encore nouveau dans Python et la programmation en général, mais cela ressemble à quelque chose comme href = "https://stackoverflow.com/questions/11729120/python-read-specific-lines-of-text"> ceci pourrait aider. Je ne comprends tout simplement pas comment cela fonctionnerait.

Des idées sur la façon dont je peux y parvenir? J'essaye également d'utiliser Python 3.x.


3 commentaires

Vous devriez essayer regex pour de telles tâches où il y a un modèle dans les chaînes. En bref, recherchez le module re de Python.


J'avais pas pensé à ça. Le défi ici est qu'il n'y a pas de modèles uniques qui n'existent pas sur d'autres lignes. Par exemple, il peut y avoir plus de 200 interfaces sur un commutateur. Je veux seulement voir ceux qui ont en fait un «modèle» ou une commande spécifique. Regex ne couvrirait que ligne par ligne, n'est-ce pas?


Ce n'est pas la façon dont cela fonctionne, ligne par ligne. Il fonctionne sur n'importe quel objet chaîne. Mais de toute façon, la réponse de Cody ci-dessous est la meilleure voie à suivre. Btw ciscoconfparse utilise des expressions régulières donc il y a des modèles ici à coup sûr.


3 Réponses :


2
votes

Il serait probablement plus facile d'utiliser une bibliothèque d'analyse de configuration Cisco plutôt que de partir des premiers principes.

Par exemple, ciscoconfparse rend votre problème aussi simple que le suivant, en créant un dict avec chaque interface mappée à une liste de ses éléments de configuration. La recherche d'autres types d'objets serait juste une question de changer l'argument en find_objects.

En supposant que nous ayons affaire à un fichier nommé test-config :

pprint.pprint({
    obj.text: [child.text.strip() for child in obj.children]
    for obj in parse.find_objects_w_child(
        parentspec=r"^interf", childspec=r"ip .*address"
    )
})

Résultat:

{'interface vlan 22': ['ip address 10.10.2.1 255.255.255.0',
                       'ip helper-address 10.10.44.1',
                       'ip helper-address 10.10.44.2'],
 'interface vlan 23': ['ip address 10.10.23.1 255.255.255.0',
                       'ip helper-address 10.10.44.1',
                       'ip helper-address 10.10.44.2']}

Modifier: En ce qui concerne votre question supplémentaire, ce serait probablement soyez prudent de lire la documentation et le tutoriel du module qui contient, entre autres, des exemples de comment rechercher des entrées avec des enfants spécifiques . Pour obtenir ce que vous demandez, vous pouvez modifier ce qui précède pour utiliser la fonction find_objects_w_child () :

import pprint
from ciscoconfparse import CiscoConfParse

parse = CiscoConfParse("test-config", syntax="ios")

pprint.pprint({
    obj.text: [child.text.strip() for child in obj.children]
    for obj in parse.find_objects(r"interface")
})


4 commentaires

Dang ... Je n'ai pas réalisé que ce module existait. Je vais lui donner une chance un post ici sur les résultats. On dirait qu'il peut fonctionner sur plus que simplement IOS, donc c'est peut-être exactement ce dont vous avez besoin. Merci!


Alors je lui ai donné une chance. On dirait que cela aidera également à atteindre quelques autres objectifs - trouver les noms de VLAN et examiner les configurations des ports d'accès. Ce que je dois comprendre pour atteindre mon objectif initial à partir de ce post, c'est de filtrer uniquement les interfaces. Dans la plupart des configurations exécutées par ce script, il y aura des tas de configurations sur chaque port d'accès. Par exemple, spanning tree ou configurations NAC. Si je cours contre une pile de cinq commutateurs, je pourrais obtenir une sortie de 240 configurations d'interface en plus des configurations IP. Les pensées?


Peut-être y a-t-il un moyen de dire «Si la sortie de ciscoconfparse contient 'ip address' ou 'ip helper-address', alors imprimez?


Merci. Je ferai un peu plus de lecture de la documentation. Je ne savais pas que vous pouviez tirer parti d'une relation parent / enfant avec ces commandes. On dirait qu'il n'en faudra pas beaucoup pour faire fonctionner ce composant.



0
votes

Voici un exemple de la ciscoconfparse recommandée ci-dessus. C'est vraiment très utile. Je me demande simplement si je peux d'une manière ou d'une autre exclure toutes les interfaces de commutation pour les appareils.

     'interface FastEthernet0/7': ['spanning-tree portfast'],
 'interface FastEthernet0/8': ['switchport access vlan 300',
                               'switchport mode access',
                               'authentication event fail action next-method',
                               'authentication event server dead action reinitialize vlan 999',
                               'authentication host-mode multi-auth',
                               'authentication order dot1x mab',
                               'authentication priority dot1x mab',
                               'authentication port-control auto',
                               'mab eap',
                               'dot1x pae authenticator',
                               'spanning-tree portfast'],
 'interface FastEthernet0/9': ['switchport access vlan 300',
                               'switchport mode access',
                               'authentication event fail action next-method',
                               'authentication event server dead action reinitialize vlan 999',
                               'authentication host-mode multi-auth',
                               'authentication order dot1x mab',
                               'authentication priority dot1x mab',
                               'authentication port-control auto',
                               'mab eap',
                               'dot1x pae authenticator',
                               'spanning-tree portfast'],
 'interface GigabitEthernet0/1': [],
 'interface GigabitEthernet0/2': [],
 'interface Vlan1': ['no ip address', 'shutdown'],
 'interface Vlan300': ['ip address 172.22.0.1 255.255.255.0',
                       'ip helper-address 10.208.111.196',
                       'ip helper-address 10.208.111.195'],
 'interface Vlan310': ['ip address 172.31.200.1 255.255.255.0',
                       'ip access-group guest-restrictions in',
                       'ip helper-address 10.208.111.195',
                       'ip helper-address 10.208.111.196'],
 'interface Vlan500': ['ip address 172.19.0.2 255.255.255.248'],


0 commentaires

0
votes

Vous pouvez utiliser TTP pour analyser le texte ci-dessus, voici le code:

[
    [
        {
            "dhcp": [
                "10.10.44.1",
                "10.10.44.2"
            ],
            "interface": "vlan 22",
            "ip": "10.10.2.1",
            "mask": "255.255.255.0"
        },
        {
            "dhcp": [
                "10.10.44.1",
                "10.10.44.2"
            ],
            "interface": "vlan 23",
            "ip": "10.10.23.1",
            "mask": "255.255.255.0"
        }
    ]
]


0 commentaires