如何使用动态音符属性名称访问从CSV文件导入的数据?也就是说,人们事先并不知道colunm的名字。它们匹配模式,并在脚本运行时从CSV文件中提取。
举个例子,考虑一个CSV文件:
"Header 1","Header A","Header 3","Header B"
0,0,0,0
1,2,3,4
5,6,7,8
我想只提取以字母结尾的列。为此,我阅读标题行并使用正则表达式提取名称,
$reader = new-object IO.StreamReader("C:\tmp\data.csv")
$line = $reader.ReadLine()
$headers = @()
$line.Split(",") | % {
$m = [regex]::match($_, '("Header [A-Z]")')
if($m.Success) { $headers += $m.value } }
这将获得我关心的所有列名:
"Header A"
"Header B"
现在,要访问CSV文件,我会像这样导入它,
$csvData = import-csv "C:\tmp\data.csv"
Import-CSV将创建一个自定义对象,该对象具有根据标题行的属性。可以通过NoteProperty名称访问字段,如此,
$csvData | % { $_."Header A" } # Works fine
这显然需要提前知道列名。我想使用我提取并存储到$headers
中的colunn名称。我该怎么做?
到目前为止我尝试过的一些事情
$csvData | % { $_.$headers[0] } # Error: Cannot index into a null array.
$csvData | % { $np = $headers[0]; $_.$np } # Doesn't print anything.
$csvData | % { $_.$($headers[0]) } # Doesn't print anything.
我可以更改脚本,因此它会编写另一个知道列名称的脚本。这是我唯一的解决方案吗?
答案 0 :(得分:3)
我想你想要这个:
[string[]]$headers = $csvdata | gm -MemberType "noteproperty" |
?{ $_.Name -match "Header [a-zA-Z]$"} |
select -expand Name
$csvdata | select $headers
选择符合条件的标题(在本例中为以字符结尾的标题),然后获取这些标题的csv数据。
答案 1 :(得分:0)
$csvData | % { $_.$(( $csvData | gm | ? { $_.membertype -eq "noteproperty"} )[0].name) }
获取第一列值和
$csvData | % { $_.$(( $csvData | gm | ? { $_.membertype -eq "noteproperty"} )[1].name) }
第二栏等等......
这就是你需要的吗?
答案 2 :(得分:0)
您可以使用自定义脚本手动解析csv:
$content = Get-Content "C:\tmp\data.csv"
$header = $content | Select -first 1
$columns = $header.Split(",")
$indexes = @()
for($i; $i -lt $columns.Count;$i++)
{
# to verify whether string end with letter matches this regex: "[A-Za-z]$"
if ($column[$i] -match "[A-Za-z]$")
{
$indexes += $i
}
}
$outputFile = "C:\tmp\outdata.csv"
Remove-Item $outputFile -ea 0
foreach ($line in $content)
{
$output = ""
$rowcol = $line.Split(",")
[string]::Join(",", ($indexes | foreach { $rowcol[$_] })) | Add-Content $outputFile
}