Szukasz wielu różnych ciągów w wielu różnych plikach dziennika?


0

Mam listę plików, które zaginęły gdzieś w naszym systemie w pracy. Mam również folder pełen 41 plików dziennika, które sumują się do 46 MB, które, mam nadzieję, zawierają wpisy dziennika dotyczące brakujących plików. Jak mogę grepować te pliki dziennika dla dowolnej wartości na mojej liście?

Lista ma strukturę jednego pliku w wierszu bez rozszerzenia pliku. Wydaje się, że kłody mają strukturę, ale nie jestem jeszcze do końca zaznajomiony z tą strukturą. Zawiera nazwy plików i ścieżki, a także to, co zostało zrobione.

Wiem, że mogę cat *wszystkie pliki dziennika i przesłać je do potoku grep. Prawdopodobnie skorzystam z -Ai, -Baby uzyskać mały kontekst z plików dziennika po znalezieniu nazwy. Używam GnuWin32 na Windowsie, więc mogę połączyć to z Powershellem, ale myślę, że zrobienie tego wymagałoby, aby jedna nazwa pliku grepsowała wszystkie 46 MB, a kiedy przechodzę do następnej nazwy pliku, zaczynam od nowa. Mam na liście 1830 plików, więc jeśli muszę zacząć od nowa z każdym, skończę czytać 46 MB tyle razy, że będę miał do czynienia z GB powtarzających się danych. Wydaje się to nieefektywne w ten sposób.

Przypuszczam, że mógłbym zbudować duże wyrażenie regularne z plików 1830 lub razem i uruchomić to raz z dziennikami, ale czy jest to wykonalne? Wyrażenie regularne wyniesie prawie 30 KB (1830 plików * średnia długość nazwy pliku około 16 znaków = 29280 bajtów, nie wspominając o kolejnych 1830 bajtach symboli potoku).

Edycja: Oto, co robię teraz, gdy jestem w folderze dzienników, a lista jest z powrotem o jeden folder:

$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

To całkowicie PowerShell. Jestem gotów użyć dowolnego narzędzia, aby przyspieszyć to, ponieważ obecnie we wszystkich plikach dziennika znajduje się 550991 linii i jest 1830 nazw plików, więc to podejście pozwala na porównanie 1 003 315 530 . Wszystko jest w pamięci, więc przynajmniej nie mam dysku I / O spowalniającego mnie. Być może uda mi się wyrwać z sytuacji, whilegdy stanie ifsię to prawdą, ale nadal będę dokonywać tak wielu porównań, nie jestem pewien, czy optymalizacja przyniesie jakieś korzyści. Działa już od pół godziny. Nie mam nic przeciwko przepisaniu mojego podejścia z linii 1, jeśli uda mi się to zrobić, zanim wrócę do domu na weekend.


Jeśli uda ci się utrzymać 46 MB w pamięci, powtórne zaczerwienienie nie stanowi problemu.
Hagen von Eitzen

@HagenvonEitzen To możliwe.
Corey Ogburn,

Odpowiedzi:


0

Bardziej efektywne byłoby wyciągnięcie nazw plików z dzienników za pomocą wyrażenia regularnego i sprawdzenie, czy każdy z nich znajduje się na liście. Może wyglądać mniej więcej tak:

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

Szukam plików, które wyglądają jak „\ coś.txt”. Będziesz musiał to zmienić.

Jeśli nadal jest zbyt wolny, a twoja niezawierająca lista jest bardzo duża, może być bardziej wydajne załadowanie jej do zestawu .NET HashSet, ale nie zrobiłbym tego, gdyby nie była potrzebna.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.