Suchen Sie nach vielen verschiedenen Zeichenfolgen in vielen verschiedenen Protokolldateien?

820
Corey Ogburn

Ich habe eine Liste von Dateien, die bei der Arbeit irgendwo in unserem System verschwunden sind. Ich habe auch einen Ordner mit 41 Protokolldateien, die bis zu 46 MB groß sind und hoffentlich Protokolleinträge für die fehlenden Dateien enthalten. Wie kann ich diese Protokolldateien für einen beliebigen Wert in meiner Liste abrufen?

Die Liste ist als eine Datei pro Zeile ohne Dateierweiterung aufgebaut. Die Protokolle scheinen eine Struktur zu haben, aber ich bin mit dieser Struktur noch nicht ganz vertraut. Es enthält Dateinamen und Pfade sowie das, was damit gemacht wurde.

Ich weiß, ich kann cat *alle Log-Dateien und Pipe an grep. Ich werde wahrscheinlich -Aund verwenden -B, um einen kleinen Kontext aus den Protokolldateien zu bekommen, wenn ein Name gefunden wird. Ich benutze GnuWin32 unter Windows, also könnte ich dies mit Powershell koppeln, aber ich denke, dafür müsste ein Dateiname alle 46 MB erreichen und wenn ich zum nächsten Dateinamen gehe, fange ich von vorne an. Ich habe 1830 Dateien in der Liste. Wenn ich also von vorne anfangen muss, werde ich so oft 46 MB lesen, dass ich mich mit GBs von sich wiederholenden Daten beschäftige. Es scheint ineffizient zu sein, es so zu machen.

Ich nehme an, ich könnte eine große Regex aus den 1830-Dateien erstellen oder sie zusammen ausführen und einmal mit den Protokollen ausführen, aber ist das machbar? Der Regex würde fast 30 KB betragen (1830 Dateien * durchschnittliche Länge des Dateinamens etwa 16 Zeichen = 29280 Bytes, um nicht 1830 Bytes Pipe-Symbole zu erwähnen).

Bearbeiten: Hier ist was ich jetzt mache, wenn ich im Protokollordner bin und die Liste einen Ordner zurück ist:

$logs = gc * $notfound = gc ../notfound.txt $logs | % { $i = 0; while ($i -lt $notfound.Count) { if ($_ -contains $notfound[$i]) { echo $_ }; $i++; } } | out-file C:\discovered.txt 

Es ist völlig Powerhell. Ich bin bereit für die Verwendung eines Tools, um dies zu beschleunigen, da momentan 550991 Zeilen in allen Protokolldateien und 1830 Dateinamen vorhanden sind. Dieser Ansatz führt also zu 1.008.313.530 Vergleichen . Es ist alles im Speicher, zumindest habe ich keine Diskette, die mich verlangsamt. Ich werde vielleicht aus dem ausbrechen, whilewenn das ifwahr wird, aber ich werde immer noch so viele Vergleiche anstellen. Es läuft schon eine halbe Stunde. Ich bin damit einverstanden, dass ich meinen Ansatz aus Zeile 1 umschreibe, wenn ich es schaffen kann, bevor ich für das Wochenende nach Hause gehe.

0
Wenn Sie es schaffen, die 46 MB im Speicher zu halten, ist das wiederholte Rotieren kein Problem. Hagen von Eitzen vor 10 Jahren 0
@HagenvonEitzen Das ist möglich. Corey Ogburn vor 10 Jahren 0

1 Antwort auf die Frage

0
dangph

Es wäre effizienter, die Dateinamen mithilfe eines regulären Ausdrucks aus den Protokollen zu ziehen und zu prüfen, ob jeder von ihnen in Ihrer Liste enthalten ist. Es könnte ungefähr so ​​aussehen:

$notfound = gc ../notfound.txt gc * | select-string -AllMatches '\\(?<filename>[^\\]+)\.txt' |  select -ExpandProperty Matches | % { $_.Groups['filename'].Value } | ? { $notfound -contains $_ } | out-file C:\discovered.txt 

Ich suche nach Dateien, die wie "\ something.txt" aussehen. Sie müssen das ändern.

Wenn es immer noch zu langsam ist und Ihre Liste nicht gefunden wird, ist es möglicherweise effizienter, sie in ein .Net HashSet zu laden. Dies würde ich jedoch nur tun, wenn dies erforderlich wäre.