1
votes

Lecture d'une zone spécifique de chaîne à partir d'un fichier

J'essaye de comprendre comment faire des trucs avec python. J'ai un fichier texte, qui contient des chaînes, c'est-à-dire:

import re
import string
filename = '11.txt'
def infile(filename):
    m1 = m2 = s1 = s2 = 0
    linecounter = 1
    lines = [1,2,3]
    colums = [2,4]
    i=0
    fin = open(filename, 'r')
    if fin.closed:
        print ('file is closed')
    lines = fin.readlines()
    for line in lines:
        if(line[0] == 'M' and line[3] == '1' and m1 == 0):
            print('---M, 1, Datetime, Error Level, DeviceId, UserId, Message---\n')
            m1 = 1
        elif (line[0] == 'M' and line[3] == '2' and m2 == 0):
            print('---M, 2, Datetime, Error Level, DeviceId, UserId, MobileId, Message---\n')
            m2 = 1
        elif (line[0] == 'S' and line[3] == '1' and s1 == 0):
            print('---S, 1, Datetime, Error Level, DeviceId, Action, Message---\n')
            s1 = 1
        elif (line[0] == 'S' and line[3] == '2' and s2 == 0):
            print('---S, 2, Datetime, Error Level, DeviceId, IP, Action, Message---\n')
            s2 = 1
        for p in re.split(",",line): // thats a check of spliting, nothing else
            print("piece="+p)
        print(line)

infile(filename)

Ce que j'essaie de faire est d'entrer dans le fichier, et si c'est la première fois qu'il y a M, 1 je devrais en imprimer texte, même si c'est S, 1 ou M, 2 ou S, 1. Je dois également imprimer uniquement les lignes sélectionnées du fichier (je ne l'ai pas encore fait mais je le ferai avec un compteur de lignes). Ce que je dois aussi faire est de n'imprimer que les colonnes sélectionnées, ce que je veux dire par colonnes, c'est qu'il y a un séparateur ',' entre les colonnes, c'est à dire si je veux imprimer 3 et 4 colonnes des lignes 1 et 2 je ne devrais imprimer que 14 / 08/2019 11:39, 4 et 14/08/2019 11:40, 100. J'ai déjà compris comment séparer les cordes avec re.split, mais je ne sais pas comment continuer. Merci.

M, 1, 14/08/2019 11:39, 4, xxxx, name, “Initialization of the system, and loading
M, 1, 14/08/2019 11:40, 100, xxxx, name, “Open Connection”
M, 1, 14/08/2019 11:40, 100, xxxx, name, “Close Connection, and reboot”
S, 1, 14/08/2019 11:40, 6, xxxx, name, We created the user in the systems
S, 1, 14/08/2019 11:41, 3, xxxx, User logged in, User tal logged in
M, 1, 14/08/2019 11:39, 4, xxxx, name, “Initialization of the system”
S, 1, 14/08/2019 11:40, 6, New User, We created the user in the systems
S, 1, 14/08/2019 11:41, 3, User logged in, User tal logged in
S, 1, 14/08/2019 11:42, 3, User logged in, User tal logged in
M, 2, 14/08/2019 11:43, 100, yyy, yura, 12345, Message


0 commentaires

5 Réponses :


0
votes

Depuis re.split (",", line) , qui renvoie un vecteur, vous pouvez accéder aux valeurs souhaitées en utilisant par exemple:

slit_str=re.split(",",line)
split_str[2] #Returns the dates
split_str[3] #Returns the number in the column after the date

Pour accélérer , vous pouvez aussi casser la boucle si m1, m2, s1 et s1 == 1, utilisez break


0 commentaires

0
votes

J'ai créé une fonction sous select_columns qui prendra un tableau d'entiers (pour les colonnes), puis divisera la ligne par le délimiteur , et retournera une chaîne de les valeurs rassemblées.

J'espère que cela vous aidera

import re
import string
filename = '11.txt'
column_list = [3, 4] #Index 1 not index 0
def infile(filename, column_list):
    m1 = m2 = s1 = s2 = 0
    linecounter = 1
    lines = [1,2,3]
    colums = [2,4]
    i=0
    fin = open(filename, 'r')
    if fin.closed:
        print ('file is closed')
    lines = fin.readlines()
    for line in lines:
        if(line[0] == 'M' and line[3] == '1' and m1 == 0):
            print('---M, 1, Datetime, Error Level, DeviceId, UserId, Message---\n')
            print(select_columns(row = line, column_list = column_list))
            m1 = 1
        elif (line[0] == 'M' and line[3] == '2' and m2 == 0):
            print('---M, 2, Datetime, Error Level, DeviceId, UserId, MobileId, Message---\n')
            print(select_columns(row = line, column_list = column_list))
            m2 = 1
        elif (line[0] == 'S' and line[3] == '1' and s1 == 0):
            print('---S, 1, Datetime, Error Level, DeviceId, Action, Message---\n')
            print(select_columns(row = line, column_list = column_list))
            s1 = 1
        elif (line[0] == 'S' and line[3] == '2' and s2 == 0):
            print('---S, 2, Datetime, Error Level, DeviceId, IP, Action, Message---\n')
            print(select_columns(row = line, column_list = column_list))
            s2 = 1
        for p in re.split(",",line): # thats a check of spliting, nothing else
            print("piece="+p)
        print(line)

def select_columns(row, column_list):
    column_split = row.split(',')
    return_string = ''
    for column in column_list:
        return_string = '{0},{1}'.format(return_string, column_split[column - 1])
    return return_string[1:] # retruns the string trimming the first comma


infile(filename, column_list)


1 commentaires

Merci! Puis-je le faire de la même manière également pour les lignes sélectionnées?



0
votes

Un moyen plus simple de le faire serait de charger le fichier dans un dataframe, puis de Filtrer les lignes en fonction des valeurs de colonne

-> Pour charger en tant que Dataframe:

data = pd.read_csv('output_list.txt', sep=" ", header=None)
data.columns = ["a", "b", "c", "etc."]
Charger des données depuis txt avec des pandas

vers filtrer les lignes en fonction des valeurs de colonne: pandas: filtrez les lignes de DataFrame avec chaînage d'opérateurs https: / /cmdlinetips.com/2018/02/how-to-subset-pandas-dataframe-based-on-values-of-a-column/


1 commentaires

Le problème avec cela est qu'il existe 4 options différentes pour les colonnes, comme M, 2 colonnes seront différentes de M, 1 colonnes.



0
votes

vous pouvez diviser la ligne et imprimer la colonne 2,3 en remplaçant la boucle for en utilisant le code ci-dessous:

14/08/2019 11:39  4
and so on.....

cela affichera:

splittedLine = line.split(",")
print(splittedLine[2],splittedLine[3])


0 commentaires

0
votes

Vous pouvez utiliser un dictionnaire pour conserver les informations concernant la première occurrence du préfixe de chaque ligne, puis utiliser le dictionnaire pour imprimer les informations en conséquence.

De plus, maintenir un mappage pour chaque type ("M, 1", "M , 2 "etc.) avec son en-tête facilitera l'impression du résultat final.

import json
from pprint import pprint
input_string = """M, 1, 14/08/2019 11:39, 4, xxxx, name, “Initialization of the system, and loading
M, 1, 14/08/2019 11:40, 100, xxxx, name, “Open Connection”
M, 1, 14/08/2019 11:40, 100, xxxx, name, “Close Connection, and reboot”
S, 1, 14/08/2019 11:40, 6, xxxx, name, We created the user in the systems
S, 1, 14/08/2019 11:41, 3, xxxx, User logged in, User tal logged in
M, 1, 14/08/2019 11:39, 4, xxxx, name, “Initialization of the system”
S, 1, 14/08/2019 11:40, 6, New User, We created the user in the systems
S, 1, 14/08/2019 11:41, 3, User logged in, User tal logged in
S, 1, 14/08/2019 11:42, 3, User logged in, User tal logged in
M, 2, 14/08/2019 11:43, 100, yyy, yura, 12345, Message"""


# Maintain mapping between the type of line, and the header corresponding to it
header_mapping = {"M, 1": ["Datetime", "Error Level", "DeviceId", "UserId", "Message"], 
    "M, 2":  ["Datetime", "Error Level", "DeviceId", "UserId", "MobileId", "Message"],
    "S, 1": ["Datetime", "Error Level", "DeviceId", "Action", "Message"],
    "S, 2": ["Datetime", "Error Level", "DeviceId", "IP", "Action", "Message"]
}
mapping = dict()

# Split the string into lines
lines = input_string.splitlines() 

for line in lines:
    split_line = line.split(", ") # Split each line using ", "
    key = split_line[0] + ", " + split_line[1] # First two elements of the split list form your key
    # Check if the key already exists. This is to ensure that our mapping dictionary contains only the first occurrence of each type.
    if not mapping.get(key, None):
        header = header_mapping[key]
        line_info = dict(zip(header, split_line[2:])) # Create dictionary with header-value mapping
        mapping[key] = line_info # Enter dictionary entry with type-values mapping

pprint(mapping)
"""
{'M, 1': {'Datetime': '14/08/2019 11:39',
          'DeviceId': 'xxxx',
          'Error Level': '4',
          'Message': '“Initialization of the system',
          'UserId': 'name'},
 'M, 2': {'Datetime': '14/08/2019 11:43',
          'DeviceId': 'yyy',
          'Error Level': '100',
          'Message': 'Message',
          'MobileId': '12345',
          'UserId': 'yura'},
 'S, 1': {'Action': 'name',
          'Datetime': '14/08/2019 11:40',
          'DeviceId': 'xxxx',
          'Error Level': '6',
          'Message': 'We created the user in the systems'}}

"""


0 commentaires