我按日期筛选了此文件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?
-NoTypeInformation
不是关于头,而是关于文件中行的数据类型。移除它以查看显示的内容。来自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:tempbagel.txt"
(Get-Content $filePath) | Where-Object{
$date,$null=$_.Split(",",2)
[datetime]$date -gt $threshold
} | Set-Content $filePath
现在您不必担心PowerShell CSV对象结构或输出,因为我们对文件本身的原始数据进行操作。
这将占用输入文件的每一行,如果解析的日期与阈值不匹配,则将其过滤掉。根据需要更改输入输出cmdlet的编码。$date,$null=$_.Split(",",2)
正在做的是拆分线路把逗号分成两部分。首先变成$date
,由于这只是一个过滤条件,我们将该行的其余部分转储到$null中。
格式正确的CSV文件必须具有列标题。在生成CSV时使用-NoTypeInformation
不会影响列标题;相反,它会影响是否包括PowerShell对象类型信息。如果您的Export-CSV
没有-NoTypeInformation
,则CSV文件的第一行将有一行看起来像#TYPE System.PSCustomObject
,如果您要在电子表格程序中打开CSV,则不需要它。
如果随后Import-CSV
,则标头(Date、Time、A、B、C)用于创建PSObject的字段,以便您可以使用标准点表示法(例如$CSV[$line].Date
)来引用它们。
在Import-CSV
上指定-Header
的功能本质上是一种"破解",允许cmdlet处理逗号分隔但不包括列标题的文件。