我使用-NoTypeInformation,那么为什么在使用Out-File时我会回头?

时间:2017-11-03 18:08:19

标签: powershell

我按日期过滤了这个文件data1.csv

2017.11.1,09:55,1.1,1.2,1.3,1.4,1 
2017.11.2,09:55,1.5,1.6,1.7,1.8,2

我没有获得-NoTypeInformation标题:

$CutOff = (Get-Date).AddDays(-2)
$filePath = "data1.csv"
$Data = Import-Csv $filePath -Header Date,Time,A,B,C,D,E

$Data2 = $Data | Where-Object {$_.Date -as [datetime] -gt $Cutoff} | convertto-csv -NoTypeInformation -Delimiter "," | % {$_ -replace '"',''} 

但是当用Out-File

重写时
$Data2 | Out-File "data2.csv" -Encoding utf8 -Force

我得到了标题,因为data2.csv包含:

Date,Time,A,B,C,D,E
2017.11.2,09:55,1.5,1.6,1.7,1.8,2

为什么我有日期,时间,A,B,C,D,E?

2 个答案:

答案 0 :(得分:6)

-NoTypeInformation不是标题,而是文件中行的数据类型。删除它以查看显示的内容。 From Microsoft

  

忽略输出中的类型信息标题。默认情况下,输出中的字符串包含#TYPE,后跟对象类型的完全限定名称。

强调我的。

CSV需要标头。这就是它制作一个原因。如果您不想在输出中看到标题,请使用Select-Object -Skip 1将其删除。

$Data | 
    Where-Object {$_.Date -as [datetime] -gt $Cutoff} | 
    ConvertTo-CSV -NoTypeInformation -Delimiter "," |
    Select-Object -Skip 1 |
    % {$_ -replace '"'}

我不会将Out-File传递给自己。你也可以在这里输入Set-Content

我猜这整个过程是将源文件保持在同一状态,只是根据日期过滤掉一些行。您可以通过解析每行中的日期来跳过大部分内容。

$threshold = (Get-Date).AddDays(-2)
$filePath = "c:\temp\bagel.txt"
(Get-Content $filePath) | Where-Object{
    $date,$null=$_.Split(",",2)
    [datetime]$date -gt $threshold
} | Set-Content $filePath

现在您不必担心PowerShell CSV对象结构或输出,因为我们会对文件本身的原始数据进行操作。

如果解析的日期与阈值不匹配,那将占用输入文件的每一行并将其过滤掉。根据需要更改输入输出cmdlet上的编码。 $date,$null=$_.Split(",",2)正在做的是分割线 将逗号分为2部分。第一个变为$date,因为这只是一个过滤条件,我们将其余部分转储到$ null。

答案 1 :(得分:2)

格式正确的CSV文件必须具有列标题。您在生成CSV时使用-NoTypeInformation不会影响列标题;相反,它会影响是否包含PowerShell对象类型信息。如果您Export-CSV没有-NoTypeInformation,则您的CSV文件的第一行会有一行看起来像#TYPE System.PSCustomObject的行,如果您 想要的话您将在电子表格程序中打开CSV。

如果随后Import-CSV,标题(日期,时间,A,B,C)用于创建PSObject的字段,以便您可以使用标准点表示法引用它们(例如, $CSV[$line].Date)。

-Header上指定Import-CSV的功能本质上是一个" hack"允许cmdlet处理以逗号分隔但不包含列标题的文件。