我有一个非常标准的CSV文件,看起来像这样:
heading1,heading2,heading3
aaaaaaaaa,bb,ccccccc
d,eeeeeeee,ff
gggggggg,hh,iiiiiiiiiii
此文件使用import-csv导入到对象。我现在想将该对象导出到具有固定记录长度,没有定界符和表头的文件中。如果导入的值对于固定文件而言太长,则应将其切除。如果导入的值太短,则这些值应保持对齐并用空格填充。
假定宽度:
heading1 is 5
heading2 is 2
heading3 is 10
基本上,输出应如下所示:
aaaaabbccccccc
d eeff
ggggghhiiiiiiiiii
请注意第3列中值末尾的空格。
算法不应完全低效-将用于转换300MB的csv文件。
我在Stackoverflow上搜索了一段时间,然后使用自定义表格格式和format-table之类的解决方案找到了一些相关的问题,但是这些解决方案似乎并不容易适应我的特定问题。
原因:专门的COTS软件需要这种非常难看/不寻常的格式。
答案 0 :(得分:3)
## Q:\Test\2018\07\10\SO_51265871.ps1
$SPC = ' ';
Import-Csv .\Input.csv |
ForEach-Object {"[{0}{1}{2}]" -f ($_.heading1+$SPC).Substring(0,5),
($_.heading2+$SPC).Substring(0,2),
($_.heading3+$SPC).Substring(0,10)
} | Set-Content .\Output.rec
格式字符串中的[]
仅用于显示长度,包括尾随空格。
示例输出:
PS> Get-Content .\Output.rec
[aaaaabbccccccc ]
[d eeff ]
[ggggghhiiiiiiiiii]
编辑:更通用的变体,从数组中获取列宽-输出相同
$CW = @(5,2,10) # array CW = ColumnWidth
Import-Csv .\Input.csv | ForEach-Object { $i = 0
"[{0}{1}{2}]" -f `
($_.heading1).PadRight($CW[$i]).Substring(0,$CW[$i++]),
($_.heading2).PadRight($CW[$i]).Substring(0,$CW[$i++]),
($_.heading3).PadRight($CW[$i]).Substring(0,$CW[$i])
} #| Set-Content .\Output.rec
答案 1 :(得分:0)
我真的不知道你为什么要这么做,但是嘿,你这样做公平。
我想我知道您要尝试执行的操作,这将为您提供一个数组,其中每一行都将数据处理为所需的格式,然后您可以将该数组循环到txt文件,日志文件中,无论您想要什么。
$spacerCSVFile = "spacers.csv"
$prinspacerCSV = Import-Csv $spacerCSVFile -header "1","2","3"
$processedArray = New-Object System.Collections.Generic.List[System.Object]
foreach($row in $prinspacerCSV) {
if ($row.1 -like "heading*") {
# do nothing for headings
} else {
$item1 = $row.1
$item2 = $row.2
$item3 = $row.3
while ($item1.length -lt 6) {
$item1 += " "
}
while ($item2.length -lt 3) {
$item2 += " "
}
while ($item3.length -lt 11) {
$item3 += " "
}
if ($item1.length -gt 5) {
$item1 = $item1.substring(0,5)
}
if ($item2.length -gt 2) {
$item2 = $item2.substring(0,2)
}
if ($item3.length -gt 10) {
$item3 = $item3.substring(0,10)
}
$processedArray += ,"$item1$item2$item3"
}
}
foreach ($item in $processedArray) {
write-host $item
}
但是我建议您值得一试,首先在此处提供一些代码,因为堆栈溢出的想法是帮助您的代码不提供它。
答案 2 :(得分:0)
这很丑陋,可能比它需要的要复杂得多,但是据我所知,这是可行的。
希望这会给您一个想法,或者只会有所帮助
$file = "C:\Logs\Test.csv"
$data = Import-Csv $file
$properties = $data |
Get-Member |
Where-Object MemberType -EQ NoteProperty |
Select Name
foreach ($line in $data){
[string]$dataout = $null
foreach ($property in $properties) {
$dataout = $dataout + $line.($property.Name)
}
if($dataout.Length -eq 20){
$dataout
}
elseif ($dataout.Length -lt 20) {
Do{
$dataout = $dataout + " "
}
Until($dataout.Length -eq 20)
$dataout
}
else {
$dataout = ($dataout.Substring(0,20))
$dataout
}
}