【问题标题】:Use PowerShell to Quickly Search Files for Regex and Output to CSV使用 PowerShell 快速搜索文件以查找正则表达式并输出到 CSV
【发布时间】:2018-09-03 12:34:42
【问题描述】:

我的目标是在一个目录中递归地搜索所有包含正则表达式的文件,并牢记速度。然后输出到一个 CSV,其中有一列包含完全匹配,另一列显示他们找到的文件。感谢用户 woxxom,我开始使用 IO.File,因为它显然比使用 Select-String 快得多。

这是我长期从事的一个项目,通过Select-String 和Export-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
       }
    }
}

【问题讨论】:

  • 为什么这个标签是excel?
  • 好电话,我删除了标签。
  • “对我的新尝试缺少什么有什么想法吗?” 不知道。什么没有按预期工作?
  • 它似乎可以识别信息,但是当我尝试将其写入文件时,它只包含最后一个结果。我以为我正在遍历所有匹配项并进行追加,但结果似乎并非如此。
  • 另外,我无法构建要写入文件的字符串。我可以将每个值写入文件,但它们最终会出现在同一列中。

标签: regex powershell


【解决方案1】:

您可以通过使用 Stream 进行读写来提高性能

    $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()

【讨论】:

  • 成功了,我不敢相信这有多快。非常感谢您提供帮助!
  • 最后一个问题,如果我想以相同的格式附加到现有的输出文件,这很容易做到吗?
  • 如果您不想创建新文件,可以附加到现有文件。将 StreamWriter 行修改为: $file2 = new-object System.IO.StreamWriter($ResultsCSV,$true) #Append or Create a new file Stream. $true 表示如果文件不存在则创建新文件。
  • 我在使用这种方法时遇到了一个问题。对于 .txt 文件,如果有一个空行,它将停止搜索该文件,因此它会丢失之后的任何内容。我尝试了几件事,但似乎无法让它继续处理文件。
  • 将while的行替换为:while (($text = $file.ReadLine()) -ne $null )。
猜你喜欢
  • 1970-01-01
  • 2011-12-24
  • 1970-01-01
  • 1970-01-01
  • 2020-08-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多