2011-12-15 6 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" 

Import-CSV는 헤더 행마다 속성을 갖는 사용자 지정 개체를 만듭니다. 하나의 필드는 NoteProperty 이름으로 액세스 할 수 있습니다.

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

이것은 분명히 미리 열 이름을 알아야합니다. 내가 추출하여 $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 | $ ($ headers [0])}).})}' – vonPryz

+0

감사합니다. 이것은 내가 필요한 것입니다. – vonPryz

+0

@vonPryz -이게 정확히 당신이 필요로하는 것입니까? 기독교 - 범죄는 없습니다. – manojlds

3

난 당신이 원하는 생각 :

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

는 (사람이 문자로 끝나는이 경우) 조건과 일치하고 그 헤더에 대한 CSV 데이터를 가져올 헤더를 선택합니다.

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 
}