我有一个CSV文件,如下所示,我需要根据特定列的值进行过滤。我不能Import-Csv
,因为文件太大而且需要很长时间。我设法使用我在网上找到的基于Excel的解决方案,但效率极低,脚本运行需要数小时。
Sample.csv
:
A,1,2,3,4,5
B,1,A,B,C,D
C,1,2,3,4
D,2,1,2,3
E,5,1,1,1
F,8,1,1,1
我希望输出为第2列大于或等于2的所有行。即:
Output.csv
:
D,2,1,2,3
E,5,1,1,1
F,8,1,1,1
如何才能更有效地解决这个问题呢?
答案 0 :(得分:3)
试试这个:
Get-Content foo.csv | Where {[int]($_.Split(',')[1]) -ge 2}
Get-Content将一次读取一行CSV文件。 Where命令将过滤传递给它的对象。如果内部条件逐渐变为$ true,则对象将在管道中传递。在这种情况下,我们在逗号上拆分行,抓住第二个字段(从零开始的索引表示索引1),将其转换为int
然后比较-ge(大于或等于)2。注意在PowerShell中,它的类型强制总是基于像-ge
这样的二元运算符的左侧(LHS)。因此,您需要确保LHS的类型为int
,因此您要比较整数而不是字符串。
答案 1 :(得分:2)
一种方法是通过OLE访问CSV作为数据库表:
$datadir = 'C:\csv\folder'
$cs = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=$datadir;" +
'Extended Properties="text;HDR=Yes;FMT=Delimited";'
$cn = New-Object Data.OleDb.OleDbConnection
$cn.ConnectionString = $cs
$cmd = $cn.CreateCommand()
$cmd.CommandText = 'SELECT * FROM [sample.csv] WHERE [col2] >= 2'
# fill a dataset with the query result
$adapter = New-Object Data.OleDb.OleDbDataAdapter $cmd
$dataset = New-Object Data.DataSet
$adapter.Fill($dataset)
# export the first table from the dataset to a new CSV
$dataset.Tables[0] | Export-Csv 'C:\Temp\output.csv' -NoType
$cn.Close()
以上假设您的源CSV路径为C:\csv\folder\sample.csv
,第二列的标头为col2
。输出CSV创建为C:\temp\output.csv
。根据需要进行调整。