使用带有11k行的Where-Object过滤的巨大(1300万行)的Import-Csv

时间:2018-11-02 13:50:25

标签: powershell csv

我有一个巨大的csv文件,其中包含约1300万行和约50列(文件#1)。我还有另一个文件,它包含约11000行,是IP地址列表(文件#2),也是第一个文件的50列之一。我该如何过滤文件#1,以便输出仅包含找到文件#2的IP地址的行?

这是我到目前为止已经尝试过的方法,但是已经运行了12个小时并且还在不断计数:

$IP = Get-Content -Path C:\Documents\File2.txt

Import-Csv C:\Documents\File1.csv | Where-Object {$_.IP -eq $IP} | Export-csv -Path C:\Documents\File3.csv -NoTypeInformation

1 个答案:

答案 0 :(得分:3)

您可以使此脚本运行得更快:

  • 无需使用Import-Csv / Export-csv。读/写线是 足够而且快得多
  • $ _。ip -in $ IP是无效的。采用 用于查找的哈希表(将是即时的)
  • 使用.net工具 而不是内置cmdlet

下面是我提到的优化脚本。运行前检查注释的行

$inFile = "C:\stack\IpTables\Data.txt"
$IPfile =  "C:\stack\IpTables\IPs.txt"
$outFile = "C:\stack\IpTables\OutData.txt"
$ipIndexInData = 47 #index of IP address column in your data file

#build a hashtable for IP look up. 
$hash = @{}
[System.IO.File]::ReadAllLines($IPfile) | foreach {$hash.Add($_, $true)}
# if IP values in your list are not unique then wrap $hash.Add() with try/catch


$fsIn = [System.IO.StreamReader]$inFile
$fsOut = [System.IO.StreamWriter]$outFile

$fsOut.WriteLine($fsIn.ReadLine()) # this will write first row with column names to out file. Comment it out if first row is data row

while (!$fsIn.EndOfStream) {

 $line = $fsIn.ReadLine()
 $row = $line -split ","

 if($hash[$row[$ipIndexInData].Trim('"')]) { # remove .Trim('"') if values in your data file are not quoted with "

    $fsOut.WriteLine($line)
 }

}