从Powershell中的CSV中删除标题
需要从CSV文件中删除标题的帮助。文件导入到的工具有非常严格的要求。最上面一行必须是标题,然后是第2行日期:2019年8月19日。第三行应该包含没有标题的数据 尝试将其导入回并使用[1..-1]表示法删除顶行,以及尝试使用从Powershell中的CSV中删除标题,powershell,csv,header,export-csv,Powershell,Csv,Header,Export Csv,需要从CSV文件中删除标题的帮助。文件导入到的工具有非常严格的要求。最上面一行必须是标题,然后是第2行日期:2019年8月19日。第三行应该包含没有标题的数据 尝试将其导入回并使用[1..-1]表示法删除顶行,以及尝试使用选择对象-skip 1将数据导入。还是不能让它工作 还尝试将对象数组写入TXT,但它只作为字段显示,而不是像CSV中那样基于选项卡。例如: 日期: 信息: 字段1: get-content "c:\users\user123\documents\adh\_$(get-date
选择对象-skip 1
将数据导入。还是不能让它工作
还尝试将对象数组写入TXT,但它只作为字段显示,而不是像CSV中那样基于选项卡。例如:
日期:
信息:
字段1:
get-content "c:\users\user123\documents\adh\_$(get-date (get-date).addDays($i) -f yyyy-MM-dd).csv" | Select-Object -Skip 1 | Set-Content "c:\users\user123\documents\adh\_$(get-date (get-date).addDays($i) -f yyyy-MM-dd).txt"
即使在我尝试删除标题后,该文件仍然包含标题。在测试环境中复制该文件,尝试添加-NoTypeInformation这可能会解决您的问题
-NoTypeInformation将删除元数据,因此在测试时要小心。我可以通过生成测试CSV重现您的问题,如下所示:
Get Process |选择ProcessName、ID、SI |导出CSV C:\temp\test.CSV-NoTypeInformation
您偶然发现的是管道的一个有趣方面。我不知道它为什么这么做的具体原因,但有两种方法可以解决这个问题,即自动将标题放回CSV:
获取内容C:\temp\test.csv |选择-跳过1 |输出文件-文件路径“C:\temp\new.csv”-NoClobber
这里需要注意的是,它不允许您覆盖使用Get Content打开的文件,因此您必须将其发送到单独的文件Get Content C:\temp\test.csv | Select-Skip 1
的结果存储到变量中,然后将该变量发送到常规的Out File调用。这将使您覆盖该文件获取包含字段头记录的.csv文件后,可以构建该文件。已生成
csmem.csv
文件,但有一个头记录。这将在前两(2)条记录上写入标题和日期,然后附加不带标题记录的.csv文件
"The Title" | Out-File -FilePath "C:\src\t\sf.csv" -Encoding ascii
(Get-Date).ToString('yyyy-MM-dd') | Out-File -FilePath "C:\src\t\sf.csv" -Encoding ascii -Append
Get-Content -Path 'C:\src\t\csmem.csv' |
Select-Object -Skip 1 |
Out-File -FilePath "C:\src\t\sf.csv" -Encoding ascii -Append
给定生成的示例文件:
> Get-Content .\_2019-08-19.csv
"COLA","ColB"
"Test1","Foo"
"Test2","Baz"
"Test3","Bar"
"Test4","Baz"
"Test5","Baz"
此脚本:
## Q:\Test\2019\08\20\SO_SO_57581085.ps1
##
$i = 1
$BaseDir = 'C:\Users\user123\Documents\adh'
# $BaseDir = (gi .).FullName
$BaseName= '_{0:yyyy-MM-dd}' -f (Get-Date).AddDays(-$i)
"Your Title`ndate: {0:M\/d\/yyyy}" -f (Get-Date).AddDays(-$i) |
Set-Content (Join-Path $BaseDir ($BaseName+'.txt')) # -Encoding if req.
Get-Content (Join-Path $BaseDir ($BaseName+'.csv')) |
Select-Object -Skip 1 |
Add-Content (Join-Path $BaseDir ($BaseName+'.txt')) # -Encoding if req.
生成此结果文件:
> Get-Content .\_2019-08-19.txt
Your Title
date: 8/19/2019
"Test1","Foo"
"Test2","Baz"
"Test3","Bar"
"Test4","Baz"
"Test5","Baz"
听起来您的起点是一个内存中的对象数组,要转换为CSV而不带标题 要获得没有标题的CSV表示,您无需使用
导出CSV
-只需通过管道传输到转换到CSV
,即可生成字符串数组,其第一个元素-标题行-您可以使用选择对象-跳过1
跳过
因此,您的整个文件可以通过单个可扩展字符串写入:
# Format the date string.
$i = 2 # sample value
$dateString = '{0:yyyy-MM-dd}' -f (Get-Date).AddDays($i)
# The input object array
# $objArray = ...
# Use an expandable here-string to write the output file.
@"
Title
$dateString
$($objArray | ConvertTo-Csv | Select-Object -Skip 1 | Out-String)
"@ | Set-Content -NoNewline "c:\users\user123\documents\adh\_$dateString.txt"
至于你所尝试的: 尝试将其导入回并使用[1..-1]表示法删除顶行
[1..-1]
不会跳过PowerShell中数组的第一个元素,因为1..-1
是一个范围表达式,可扩展到以下索引列表:1,0,-1
;也就是说,您正提取3个元素:第二个(1
),第一个(0
),最后一个(-1
)
还尝试将对象数组写入TXT,但它只作为字段显示,而不是像CSV中那样基于选项卡。例如:
这听起来像是您使用了非导出Csv的东西将内存中的对象数组发送到了*.txt
文件,而这不会给您Csv输出;听起来像是您使用了
或输出文件
,其中对象的格式与它们打印到控制台的方式相同,这是一种显示格式,不适合编程处理
获取内容….csv |选择对象-跳过1 |设置内容….txt
假设输入*.csv
文件是用导出Csv-notype信息
如果未使用-NoTypeInformation
,请使用-Skip 2
,即跳过另一行,以便跳过默认情况下作为第一行输出的导出Csv的类型注释行
注意:Windows PowerShell中导出Csv的这一违反直觉的默认行为已在PowerShell Core中修复。我认为导出Csv时,-NoTypeInformation
只是删除了该类型标题。我认为它对实际的CSV头没有任何影响。我可能是错的,虽然听起来您认为OP的问题是试图回写正在读取的同一个文件,但事实并非如此,因为问题中的命令会写入另一个文件(*.txt
)。至于原因:管道流(逐个对象处理输入对象),因此write命令尝试将行写入仍然打开的文件,因为read命令(Get Content
)尚未完成读取。一个简单的解决方法是将获取内容
调用包含在(…)
中,这将强制提前阅读:(获取内容…)…|设置内容…
。不过,数据丢失的风险很小。您是否可以选择一个答案?