我需要从CSV文件中删除多个列,而不在Powershell中导入CSV文件。下面是我输入CSV的示例以及我希望输出CSV的外观。
Input.csv
A,1,2,3,4,5
B,6,7,8,9,10
C,11,12,13,14,15
d,15,16,17,18,19,20
Idealoutput.csv
A,3,5-
B,8,10
C,13,15
d,17,20
我尝试过以下代码,但它给了我很多错误,并说我不能使用"删除"方法这种方式(我过去做过的)......有什么想法吗?
$Workbook1 = $Excel.Workbooks.open($file.FullName)
$header = $Workbook1.ActiveSheet.Range("A1:A68").EntireRow
$unneededcolumns1 = $Workbook1.ActiveSheet.Range("A1:O1").EntireColumn
$unneededcolumns2 = $Workbook1.ActiveSheet.Range("B1:K1").EntireColumn
$unneededcolumns3 = $Workbook1.ActiveSheet.Range("F1:I1").EntireColumn
$unneededcolumns4 = $Workbook1.ActiveSheet.Range("G1:I1").EntireColumn
$unneededcolumns5 = $Workbook1.ActiveSheet.Range("H1:O1").EntireColumn
$unneededcolumns6 = $Workbook1.ActiveSheet.Range("J1:AL1").EntireColumn
$unneededcolumns7 = $Workbook1.ActiveSheet.Range("K1").EntireColumn
$unneededcolumns8 = $Workbook1.ActiveSheet.Range("L1:AK1").EntireColumn
$unneededcolumns9 = $Workbook1.ActiveSheet.Range("F1:I1").EntireColumn
$unneededcolumns10 = $Workbook1.ActiveSheet.Range("M1:AB1").EntireColumn
$unneededcolumns11 = $Workbook1.ActiveSheet.Range("N1:X1").EntireColumn
$unneededcolumns12 = $Workbook1.ActiveSheet.Range("O1:BA1").EntireColumn
$unneededcolumns13 = $Workbook1.ActiveSheet.Range("P1:U1").EntireColumn
$header.Delete()
$unneededcolumns1.Delete()
$unneededcolumns2.Delete()
$unneededcolumns3.Delete()
$unneededcolumns4.Delete()
$unneededcolumns5.Delete()
$unneededcolumns6.Delete()
$unneededcolumns7.Delete()
$unneededcolumns8.Delete()
$unneededcolumns9.Delete()
$unneededcolumns10.Delete()
$unneededcolumns11.Delete()
$unneededcolumns12.Delete()
$unneededcolumns13.Delete()
$Workbook1.SaveAs("\\output.csv")
答案 0 :(得分:4)
我还是要添加这个,因为我希望说服你避免使用Excel是多么容易。
$source = "c:\temp\file.csv"
$destination = "C:\temp\newfile.csv"
(Import-CSV $source -Header 1,2,3,4,5,6 |
Select "1","4","6" |
ConvertTo-Csv -NoTypeInformation |
Select-Object -Skip 1) -replace '"' | Set-Content $destination
我们将任意标题分配给对象,这样我们就可以按位置调用第1列,第4列和第6列。导出后,文件将包含以下内容,这些内容与我认为您想要的内容相匹配,而不是您在问题中的内容。你的最后一行有一个额外的值(20),我不知道它是否有意。
A,3,5
B,8,10
C,13,15
D,17,19
如果这不可行,我真的很感兴趣。
Excel方法
好吧,所以文件很大,所以Import-CSV不是一个可行的选择。保持你的excel想法我想出了这个。它将做的是获取列索引并删除那些不在这些索引中的列。
等等你说?...由于列索引在删除列时发生变化,因此无法正常工作。使用我们想要保留的索引,我们得到基于工作表UsedRows
的删除反转。然后,我们将每个列删除并删除一个等于数组位置的值。原因是当实际删除列时,已经调整了下一个值以考虑该移位。
$file = "c:\temp\file.csv"
$ColumnsToKeep = 1,4,6
# Create the com object
$excel = New-Object -comobject Excel.Application
$excel.DisplayAlerts = $False
$excel.visible = $False
# Open the CSV File
$workbook = $excel.Workbooks.Open($file)
$sheet = $workbook.Sheets.Item(1)
# Determine the number of rows in use
$maxColumns = $sheet.UsedRange.Columns.Count
$ColumnsToRemove = Compare-Object $ColumnsToKeep (1..$maxColumns) | Where-Object{$_.SideIndicator -eq "=>"} | Select-Object -ExpandProperty InputObject
0..($ColumnsToRemove.Count - 1) | %{$ColumnsToRemove[$_] = $ColumnsToRemove[$_] - $_}
$ColumnsToRemove | ForEach-Object{
[void]$sheet.Cells.Item(1,$_).EntireColumn.Delete()
}
# Save the edited file
$workbook.SaveAs("C:\temp\newfile.csv", 6)
# Close excel and release the com object.
$workbook.Close($true)
$excel.Quit()
[void][System.Runtime.Interopservices.Marshal]::ReleaseComObject($excel)
Remove-Variable excel
即使在阅读"correct" way to do it之后,我仍然遇到Excel问题仍未解决的问题。内在的逻辑是重要的。不要忘记根据需要更改路径。
答案 1 :(得分:0)
这是我使用的更好的方法,但是它不是大型文件上性能最高的方法。两者都已经过1GB文件的测试。
Powershell:
Import-Csv '.\inputfile.csv'
| select ColumnName1,ColumnName2,ColumnName3
| Export-Csv -Path .\outputfile.csv -NoTypeInformation
如果要摆脱该工具添加的那些讨厌的引号,请升级到Powershell 7。
PowerShell 7 +:
Import-Csv '.\inputfile.csv'
| select ColumnName1,ColumnName2,ColumnName3
| Export-Csv -Path .\outputfile.csv -NoTypeInformation -UseQuotes Never