
我有一份在我們工作系統中某處遺失的文件清單。我還有一個資料夾,其中包含 41 個日誌文件,總計達 46 MB,希望其中包含與遺失文件相關的日誌條目。如何在這些日誌檔案中尋找清單中的任何值?
此清單的結構為每行一個文件,沒有文件副檔名。日誌似乎確實有一個結構,但我還不完全熟悉該結構。它確實包含文件名和路徑以及對其執行的操作。
我知道我可以將cat *
所有日誌文件並將其通過管道傳輸到grep
.當找到名稱時,我可能會使用-A
和-B
從日誌檔案中獲取一些上下文。我在 Windows 上使用 GnuWin32,因此我可以將其與 Powershell 結合使用,但我認為這樣做需要一個檔案名稱 grep 全部 46 MB,當我移動到下一個檔案名稱時,我會重新開始。我的清單中有 1830 個文件,因此如果我必須從每個文件開始,我最終會多次讀取 46 MB 的文件,以至於需要處理 GB 的重複資料。這樣做似乎效率很低。
我想我可以建立一個包含 1830 個檔案 ord 的大型正規表示式,然後針對日誌運行一次,但這可行嗎?正規表示式將接近 30KB(1830 個檔案 * 大約 16 個字元的檔案名稱平均長度 = 29280 位元組,更不用說另外 1830 位元組的管道符號)。
編輯:這是我現在在日誌資料夾中所做的事情,並且列表是前一個資料夾:
$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
這完全是powershell。我準備好使用任何工具來加快速度,因為現在所有日誌檔案中總共有 550991 行,並且有 1830 個檔案名,因此這種方法正在1,008,313,530 次比較。一切都在記憶體中,所以至少我沒有磁碟 I/O 拖慢我的速度。while
如果這成為現實,我也許能夠擺脫困境if
,但我仍然會進行很多比較,我不確定優化是否真的會有任何好處。已經運行了半小時了。如果我能在周末回家之前完成的話,我可以重寫第一行的方法。
答案1
透過正規表示式從日誌中提取檔案名稱並查看每個檔案名稱是否在您的清單中會更有效。它可能看起來像這樣:
$notfound = gc ../notfound.txt
gc * |
select-string -AllMatches '\\(?<filename>[^\\]+)\.txt' |
select -ExpandProperty Matches |
% { $_.Groups['filename'].Value } |
? { $notfound -contains $_ } |
out-file C:\discovered.txt
我正在搜尋類似於“\something.txt”的文件。你必須改變這一點。
如果它仍然太慢且您的 notfound 清單非常大,那麼將其載入到 .Net HashSet 中可能會更有效,但除非需要,否則我不會這樣做。