使用 PowerShell 打开大型 csv 文件并导出特定列

Using PowerShell to open large csv files and exporting specific columns

我正在使用以下命令获取前 1,000 行数据:

Get-Content -First 1000 'C:\Users\Inspiron\Desktop\base.csv' | Out-File 'C:\Users\Inspiron\Desktop\sample.csv'

但是,我该如何调整这个命令来获取数据范围。例如,要提取第 700 行到第 900 行之间的间隔。

另一件事,我怎么能只导出几个变量。例如,我的数据库有 120 列,但我只想保存变量年份(第 1 列)、出生日期(第 4 列)和原籍国(第 100 列)。

我建议使用 import-csv 而不是 get-content

实现此目的的一种方法是使用类似的东西:

$csv = Import-CSv $csvPATH 
$rangeselect = $csv[700..900]

只需编写一个快速测试,您应该会得到类似的结果(我自己在更小的范围之间进行选择):

test test1 test2
---- ----- -----
8    9     10   
9    10    11   
10   11    12   
11   12    13   
12   13    14   
13   14    15   
14   15    16   
15   16    17   
16   17    18

关于选择特定的列,您也可以使用 import-csv 来实现。以上面为例,您可以添加:

$specificcol = $rangeselect.test1

您可以看到 .test1 专门针对一个列并使用它来应用到您试图抓取的内容。

有几种方法可以解决这个问题。建筑物

$InCsv  = 'C:\Users\Inspiron\Desktop\base.csv'
$OutCsv = 'C:\Users\Inspiron\Desktop\sample.csv'
$Props  = "year","date of birth","state of origin"

$InCsv = Import-Csv $InCsv
$rangeselect = $InCsv[700..900] # You could use variables here too...

$rangeselect | 
Select-Object $Props |
Export-Csv -Path $OutCsv -NoTypeInformation

这需要额外的步骤来选择您想要的属性并将它们 re-exporting 到一个新的 CSV 文件中。

注意:这不太可能,但如果您处理的是非常大的文件,则此方法可能会出现内存问题。它预先将整个文件读入内存,并将其存储在 $csv 变量中。如果系统受内存限制,也可能发生这种情况,但这种情况很少见。

从技术上讲,您不需要分配 $rangeselect 变量,您可以直接在 Import-Csv 命令上使用范围运算符“..”,例如:

(Import-Csv $InCsv)[700..900] | 
Select-Object $Props |
Export-Csv -Path $OutCsv -NoTypeInformation

这里,(..)在引用之前先完成读取所有的CSV数据,所以应该是一样的。


如果您想在初始示例的基础上进行构建。它的优点是只读取前 1000 行,很可能绕过任何内存限制:

$InCsv  = 'C:\Users\Inspiron\Desktop\base.csv'
$OutCsv = 'C:\Users\Inspiron\Desktop\sample.csv'
$Props  = "year","date of birth","state of origin"
$Skip   = 700
$First  = 200

Get-Content -First 1000 $InCsv | 
ConvertFrom-Csv |
Select-Object -Skip $Skip -First $First -Property $Props |
Export-Csv -Path $OutCsv -NoTypeInformation

这实际上是一个带有一些方便变量的 one-liner。它利用了 Select-Object 中的参数。请注意,它也仅 returns 您要求的属性,因此将输出仅包含该数据的新 CSV 文件。


您也可以结合使用这些方法,因为 Select-Object 允许使用 -Skip-First 以及 -Last 参数进行一些基本的初始过滤。这可能看起来像:

$InCsv  = 'C:\Users\Inspiron\Desktop\base.csv'
$OutCsv = 'C:\Users\Inspiron\Desktop\sample.csv'
$Props  = "year","date of birth","state of origin"
$Skip   = 699
$First  = 200

Import-CSv $InCsv |
Select-Object -Skip 700 -First 200 -Property $Props |
Export-Csv -Path $OutCsv -NoTypeInformation

在此示例中,您可能需要玩弄边界。但是,它实际上仍然是 one-liner 并且有可能得到您正在寻找的东西。

注意:Select-Object可以告诉管道左边的命令停止发送数据。但是,我不确定每个 cmdlet 是否都能正确反应,因此与 Get-Content 方法相比,性能可能会有所不同。这可能只有在你处理更大的文件时才重要,否则我会采用任何被认为更具可读性 and/or 可维护性的方法...