Nach vielen verschiedenen Zeichenfolgen in vielen verschiedenen Protokolldateien suchen?

Nach vielen verschiedenen Zeichenfolgen in vielen verschiedenen Protokolldateien suchen?

Ich habe eine Liste von Dateien, die irgendwo in unserem System bei der Arbeit verschwunden sind. Ich habe auch einen Ordner voller 41 Protokolldateien mit einer Gesamtgröße von 46 MB, die hoffentlich Protokolleinträge zu den fehlenden Dateien enthalten. Wie kann ich diese Protokolldateien nach einem Wert in meiner Liste durchsuchen?

Die Liste ist als eine Datei pro Zeile ohne Dateierweiterung strukturiert. Die Protokolle scheinen eine Struktur zu haben, aber ich bin mit dieser Struktur noch nicht ganz vertraut. Sie enthält Dateinamen und -pfade sowie Angaben dazu, was damit gemacht wurde.

Ich weiß, dass ich cat *alle Protokolldateien lesen und an weiterleiten kann grep. Ich werde wahrscheinlich -Aund verwenden -B, um ein wenig Kontext aus den Protokolldateien zu erhalten, wenn ein Name gefunden wird. Ich verwende GnuWin32 unter Windows, also könnte ich dies mit Powershell koppeln, aber ich denke, das würde erfordern, dass ein Dateiname alle 46 MB durchsucht und ich beim Wechseln zum nächsten Dateinamen von vorne beginne. Ich habe 1830 Dateien in der Liste, also wenn ich bei jeder neu beginnen muss, werde ich am Ende 46 MB so oft lesen, dass ich mit GBs sich wiederholender Daten zu tun habe. Es scheint ineffizient, es auf diese Weise zu tun.

Ich nehme an, ich könnte einen großen regulären Ausdruck aus den 1830 verknüpften Dateien erstellen und diesen einmal mit den Protokollen ausführen, aber ist das machbar? Der reguläre Ausdruck wäre fast 30 KB groß (1830 Dateien * durchschnittliche Länge des Dateinamens von etwa 16 Zeichen = 29280 Byte, ganz zu schweigen von weiteren 1830 Byte an Pipe-Symbolen).

Bearbeiten:Folgendes mache ich jetzt, wenn ich mich im Protokollordner befinde und die Liste einen Ordner weiter hinten liegt:

$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 komplett Powershell. Ich bin bereit, jedes Tool zu verwenden, um dies zu beschleunigen, denn im Moment gibt es 550991 Zeilen in allen Protokolldateien zusammen und es gibt 1830 Dateinamen, also macht dieser Ansatz1.008.313.530 Vergleiche. Es ist alles im Speicher, also werde ich zumindest nicht durch Festplatten-E/A ausgebremst. Ich kann vielleicht ausbrechen, whilewenn das ifzutrifft, aber ich werde trotzdem so viele Vergleiche anstellen, dass ich nicht sicher bin, ob eine Optimierung wirklich etwas bringt. Es läuft bereits seit einer halben Stunde. Ich bin damit einverstanden, meinen Ansatz von Zeile 1 an neu zu schreiben, wenn ich damit fertig werde, bevor ich ins Wochenende nach Hause gehe.

Antwort1

Es wäre effizienter, die Dateinamen über einen regulären Ausdruck aus den Protokollen zu ziehen und zu prüfen, ob jeder davon in Ihrer Liste enthalten ist. Das 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 "\irgendwas.txt" aussehen. Das müssen Sie ändern.

Wenn es immer noch zu langsam ist und Ihre Liste der nicht gefundenen Einträge sehr groß ist, ist es möglicherweise effizienter, sie in ein .Net HashSet zu laden, aber ich würde das nicht tun, es sei denn, es ist unbedingt erforderlich.

verwandte Informationen