staging.inyokaproject.org

[Python] Datei durchsuchen nach string - Effektivität?

Status: Ungelöst | Ubuntu-Version: Ubuntu 16.04 (Xenial Xerus)
Antworten |

halloICKEbins

Avatar von halloICKEbins

Anmeldungsdatum:
12. September 2017

Beiträge: 226

Abend,

habe ein Script geschrieben, welches mir den Inhalt aller Dateien in einem Verzeichnis durchsucht. Als Ausgabe habe ich dann Dateiname, Zeilennummer und die Positionen. Das funktioniert auch.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import os

path='/home/user/files/'

for filename in os.listdir(path):
    with open(path + filename, "r") as f:
        searchlines = f.readlines()
        linecount = 0
        for line in searchlines:
            linecount = linecount + 1             
            location = -1
            first_run = "yes"
            positions = ""
            while True:
                location = line.find("56", location + 1)
                if location == -1: 
                    break
                else:
                    if first_run == "yes":
                        positions = str(filename) + str(" - ") + str(linecount) + str(" - ") +  str(location)                     
                        first_run = "no"                    
                    else:                 
                        positions = str(positions) + str(" | ") + str(location)
            if positions != "":            
                print (positions)  

Inhalt einer solcher Datei ist:

Sep 07 12:00:29.323894 rule 5/(match) block in on em0: 11.22.33.44.55555 > 11.22.33.44.55555: S 1351977941:1351977941(0) win 43442
Sep 07 12:00:51.047400 rule 5/(match) block in on em0: 11.22.33.44.55555 > 11.22.33.44.55555: S 3224879997:3224879997(0) win 32233 <mss 1460,nop,wscale 0,nop,nop,sackOK> (DF)
...

Da ca. 1000 Dateien a 2.000 Zeilen durchsucht werden sollen, steht hier die Frage nach der Effektivität im Raum ... gibt es Python effektiver Mittel zur Durchsuchen und Auswertung von Dateien???

Für Verbesserung bzw. Vereinfachungen in meinem Quellcode bin ich selbstverständlich auch dankbar. 😉

Marc_BlackJack_Rintsch Team-Icon

Ehemalige
Avatar von Marc_BlackJack_Rintsch

Anmeldungsdatum:
16. Juni 2006

Beiträge: 4735

@halloICKEbins: Ich denke wir hatten irgendwann schon einmal das man Pfadteile nicht mit + sondern mit os.path.join() zusammen setzen sollte.

Die komplette Datei mit der readlines()-Methode auf einmal in den Speicher zu laden ist nicht nötig.

Wenn man zusätzlich zu den Elementen eines Iterators eine fortlaufende Zahl benötigt, nimmt man die enumerate()-Funktion statt selbst einen Wert hoch zu zählen.

Es wird zu viel mit Zeichenketten statt mit den passenden Datentypen gearbeitet. Wenn man eine Variable mit 'yes' und 'no' hat und diese Zeichenketten gar nicht tatsächlich irgendwo als Zeichenketten verwendet, dann möchte man eigentlich einen Wahrheitswert (True/False) verwenden. first_run braucht man aber gar nicht wenn man nicht das sammeln der Positionen und das Aufbauen einer Zeichenkette für die Ausgabe vermischen würde. Also wenn positions einfach nur eine Liste mit Positionen oder Teilzeichenketten ist und man erst am Ende eine Zeichenkette mit dem Inhalt davon aufbaut.

Den Einzelwert location und die gesammelten locations dann aber positions zu nennen ist verwirrend.

Ungetestet:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
    path = '/home/user/files/'

    for filename in os.listdir(path):
        with open(os.path.join(path, filename)) as in_file:
            for line_number, line in enumerate(in_file, 1):
                positions = list()
                position = -1
                while True:
                    position = line.find('56', position + 1)
                    if position == -1:
                        break
                    positions.append('{}:{}'.format(line_number, position))
                            
                if positions:
                    print('{} - {}'.format(filename, ' | '.join(positions)))

Du verwechselst übrigens Effektivität mit Effizienz. ☺

halloICKEbins

(Themenstarter)
Avatar von halloICKEbins

Anmeldungsdatum:
12. September 2017

Beiträge: 226

Stimmt natūrlich mit der Effizienz 😀 Testen mache ich morgen erst!!

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13242

Ich würde auch die Positionen nicht immer als Strings an einen String anhängen. Effizienter müsste sein, sie einfach direkt auszugeben oder aber als Zahlen in einem Array zu sammeln und dann am Stück zu konvertieren.

Ich weiß nicht, was Du mit den Daten weiter machen willst und insbesondere, ob Du die Position in der Zeile brauchst, aber fgrep kann auch schon recht viel davon. Probier mal:

1
fgrep -nborH 56 /home/user/files
Antworten |