根据行值

时间:2015-07-13 21:25:00

标签: powershell csv

我有一个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

如何才能更有效地解决这个问题呢?

2 个答案:

答案 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。根据需要进行调整。