2016-10-11 52 views
0

我的目標是爲所有包含正則表達式的文件以最快的速度遞歸地搜索目錄。然後輸出到具有包含完全匹配的列的CSV,而另一列顯示它們被發現的文件。感謝用戶woxxom,我開始玩IO.File,因爲它明顯比使用Select-String快得多。使用PowerShell快速搜索正則表達式的文件並輸出爲CSV

這是一個我一直在努力工作很長時間的項目,通過Select-StringExport-Csv完成,但這是一個相當緩慢的過程。

對於我錯過的新嘗試有何想法?

$ResultsCSV = "C:\TEMP\Results.csv" 
$Directory = "C:\TEMP\examples" 
$RX = "(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(?:\.|dot|\[dot\]|\[\.\])){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)" 
$TextFiles = Get-ChildItem $Directory -Include *.txt*,*.csv*,*.rtf*,*.eml*,*.msg*,*.dat*,*.ini*,*.mht* -Recurse 
$out = [Text.StringBuilder] 

foreach ($FileSearched in $TextFiles) { 
    $text = [IO.File]::ReadAllText($FileSearched) 
    foreach ($match in ([regex]$RX).Matches($text)) { 
     if (!(Test-Path $ResultsCSV)) { 
      'Matches,File Path' | Out-File $ResultsCSV -Encoding ASCII 
      $out.AppendLine('' + $match.value + ',' + $FileSearched.fullname) 
      $match.value | Out-File $ResultsCSV -Encoding ascii -Append 
      $FileSearched.Fullname | Out-File $ResultsCSV -Encoding ascii -Append 
      $out.ToString() | Out-File $ResultsCSV -Encoding ascii -Append -NoNewline 
     } 
    } 
} 
+0

爲什麼這個標籤Excel中的表現? – xidgel

+0

良好的通話,我刪除了標籤。 – MrMr

+0

*「有什麼想法,我失去了我的新嘗試?」*不知道。什麼不按預期工作? –

回答

2

可以加速通過使用流進行讀取和寫入

$ResultsCSV = "C:\TEMP\Results.csv" 
    $Directory = "C:\TEMP\examples" 
    $RX = "(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(?:\.|dot|\[dot\]|\[\.\])){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)" 

    $TextFiles = Get-ChildItem $Directory -Include *.txt*,*.csv*,*.rtf*,*.eml*,*.msg*,*.dat*,*.ini*,*.mht* -Recurse 

    $file2 = new-object System.IO.StreamWriter($ResultsCSV) #output Stream 
    $file2.WriteLine('Matches,File Path') # write header 

    foreach ($FileSearched in $TextFiles) { #loop over files in folder 

     # $text = [IO.File]::ReadAllText($FileSearched) 
     $file = New-Object System.IO.StreamReader ($FileSearched) # Input Stream 

     while ($text = $file.ReadLine()) {  # read line by line 
      foreach ($match in ([regex]$RX).Matches($text)) { 
        # write line to output stream 
        $file2.WriteLine("{0},{1}",$match.Value, $FileSearched.fullname) 
      } #foreach $match 
     }#while $file 
     $file.close(); 
    } #foreach 
    $file2.close() 
+0

這樣做的竅門,我不能相信這是多快。非常感謝您幫助解決這個問題! – MrMr

+0

最後一個問題,如果我想以相同的格式附加到現有的輸出文件,這可以輕鬆完成嗎? – MrMr

+1

如果你不想創建一個新的文件,你可以附加到一個現有的文件。將StreamWriter行修改爲:$ file2 = new-object System.IO.StreamWriter($ ResultsCSV,$ true)#Append或創建一個新文件流。 $ true表示如果新文件不存在,則創建新文件。 –