2011-12-15 126 views
1

如何通過使用動態註釋屬性名稱訪問從CSV文件導入的數據?也就是說,一個人事先不知道這個colunm的名字。它們匹配一個模式,並在腳本運行時從CSV文件中提取。Powershell:通過動態變量名稱獲取變量

對於一個例子,考慮一個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" 

進口CSV將創建一個具有屬性,每個標題行的自定義對象。人們可以通過NoteProperty名稱來訪問字段,

$csvData | % { $_."Header A" } # Works fine 

這顯然需要一個人事先知道列名。我想使用我提取的colunn名稱並將其存儲到$headers。我會怎麼做?

有些事情我已經試過到目前爲止

$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

是排在我的腦海裏的第一件事(和唯一的一個...對不起)是:

$csvData | % { $_.$(($csvData | gm | ? { $_.membertype -eq "noteproperty"})[0].name) } 

爲獲得第一的列值和

$csvData | % { $_.$(($csvData | gm | ? { $_.membertype -eq "noteproperty"})[1].name) } 

爲第二列等上....

這是你所需要的?

+0

差不多。它需要一個人事先知道索引,但可以通過添加類似的搜索來很容易地修復:`$ csvData | %{$ _。$(($ csvData | gm |?{$ _。membertype -eq「noteproperty」and $ _。Name-like $($ headers [0])}).name)}` – vonPryz 2011-12-16 05:48:24

3

我想你想要這樣的:

[string[]]$headers = $csvdata | gm -MemberType "noteproperty" | 
         ?{ $_.Name -match "Header [a-zA-Z]$"} | 
         select -expand Name 
$csvdata | select $headers 

選擇相匹配的條件(在這種情況下,那些與字符結尾),然後獲取這些頭CSV數據的報頭。

0

可以使用自定義腳本到CSV手動解析:

​​