我在PowerShell中有一个脚本,用于从StreamReader构建一个DataTable,它读取.csv或.txt文件(以逗号分隔)并在数据库中插入数据表。
我的源文件包含双引号内的逗号数据,例如:
ID,Desc,Obs
1234,"Some text, More Text, Text again","Text"
问题是当我要分行时:
$datatable = New-Object System.Data.DataTable
$src = "My comma delimited file (.txt/.csv)"
$reader = New-Object IO.StreamReader($src)
$header = Get-Content -Path $src | select -First 1
$columns = $header.Split(",")
foreach ($column in $columns) {
$datatable.columns.add($column)
}
while(($line = $reader.ReadLine()) -ne $null){
$line = $line -split(",")
由于双引号中的逗号,分割给了我5列而不是3。
我不想删除双引号内的逗号。数据将按如下方式插入:某些文本,更多文本,文本再次
如何解决此问题?
答案 0 :(得分:1)
解决方案1 - ConvertFrom-CSV:
保存标题并使用page1
为您解析它。 Haven没有在大文件上测试它,但它不必将整个文件加载到内存中,所以它应该至少可以工作。例如:
ConvertFrom-Csv
测试:
#Create samplefile
@"
ID,Desc,Obs
1234,"Some text, More Text, Text again","Text"
5678,"Some text, More Text, Text again and again",Text2
$(1..100000 | % { "$_,`"Some text$_, More Text$_, Text again and again$_`",Text$_`n" })
"@ -split "`n" | % { $_.trim() } | Set-Content D:\Downloads\test.txt
$datatable = New-Object System.Data.DataTable
$src = "D:\Downloads\test.txt"
$reader = New-Object IO.StreamReader($src)
#Get header and split to columns
$columns = $reader.ReadLine() -split ','
foreach ($column in $columns) {
$datatable.columns.add($column)
}
while(($line = $reader.ReadLine()) -ne $null){
#Let ConvertFrom-CSV do the heavy-lifting by making it convert one "csv-file" per line using a known header
$obj = $line | ConvertFrom-Csv -Header $columns
$row = $datatable.NewRow()
$row.ID = $obj.ID
$row.Desc = $obj.Desc
$row.Obs = $obj.Obs
$datatable.Rows.Add($row)
}
解决方案2 - TextFieldParser: VisualBasic-assembly有一个TextFieldParser类,可以理解引用的字段。由于直接使用.NET时开销较少,因此执行速度更快(在我的100k csv测试中速度提高50%)。尝试:
#Show available columns
$datatable.Columns.Caption
ID
Desc
Obs
#Show datatable
$datatable
ID Desc Obs
-- ---- ---
1234 Some text, More Text, Text again Text
5678 Some text, More Text, Text again and again Text2
答案 1 :(得分:0)
试试这个:
$csv=import-csv "C:\temp\vminfo.csv"
$datatable = New-Object System.Data.DataTable
#Add all columns
$columnsname=$csv | Get-Member -MemberType NoteProperty | %{ $datatable.columns.add($_.Name) }
#Add datas by column name
$csv | %{
$newrow=$datatable.NewRow()
$rowcsv=$_
$columnsname | %{$newrow[$_]=$rowcsv."$_"}
$datatable.Rows.Add($newrow)
}