2015-04-14 50 views
1

我有CSV文件,其中有很多列。我需要转换几个列,例如,某些日期列有文本字符串“Missing”,我想将“Missing”替换为空字符串,等等。使用powershell转换CSV文件

以下代码可能工作,但它会很长因为有很多列。这是写一个更好的方法吗?

Import-Csv $file | 
    select @( 
     @{l="xxx"; e={ ....}}, 
     # repeat many times for each column.... 
) | export-Csv 
+0

你的文件没有标题行吗? – mjolinor

+0

是的,csv文件有标题。 – ca9163d9

+0

您可以使用命令行查找和替换工具,如'FNR.EXE'在命令行上执行此操作,它可能会更快。 –

回答

2

你可以使用一个命令行式风格,而不是流水线式风格:

$records = Import-Csv $file 

foreach ($record in $records) 
{ 
    if ($record.Date -eq 'Missing') 
    { 
     $record.Date = '' 
    } 
} 

$records | Export-Csv $file 

编辑:要使用流水线式的,你可以做到这一点像这样:

import-csv $file | 
    select -ExcludeProperty Name1,Name2 -Property *,@{n='Name1'; e={"..."}},@{n='Name2'; e={'...'}} 

The *是一个匹配所有属性的通配符。我找不到一种更好的方式来格式化代码,所以它看起来很丑。

+0

我认为这种方法可能并不理想,因为操作提到可能会有许多需要解决日期的列。这仍然会工作。 – Matt

+0

@Matt,虽然他只是表示他不想在代码中指定所有未更改的列。 –

+0

流水线效率会更高,因为它可能不需要读取内存中的整个csv文件?缺点是它可能会改变列的顺序(在我的情况下也不重要)。 – ca9163d9

0

如果您想要做的只是查找替换,您并不需要将它作为CSV读取。

你可以这样做,而不是:

Get-Content $file | %{$_.ToString().Replace("Missing", "")} | Out-File $file 
+0

当你将它们连接到同一个管道中时,你可能应该将输出文件更改为不同的输入文件。无论是或者你打破了管道,并将输入数据保存到一个变量,然后你输出在不同的线路上。 – Matt

+0

@Matt - 你能澄清你的意思吗? –