通过动态变量名获取变量

时间:2011-12-15 19:23:41

标签: powershell parameters

如何使用动态音符属性名称访问从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.

我可以更改脚本,因此它会编写另一个知道列名称的脚本。这是我唯一的解决方案吗?

3 个答案:

答案 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
}