使用 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 可维护性的方法...
我正在使用以下命令获取前 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 可维护性的方法...