新创建的列是空的....为什么?

时间:2015-12-08 06:41:22

标签: csv powershell

我尝试在PowerShell中执行一项简单的任务,其中为CSV文件中的多个列计算了一些基本统计信息。我差不多完成了,但是我不断收到一个错误,我创建的新列就是Nul​​l。我不知道在哪里出错了。

具体而言,导致错误的代码行是

$STATS2.Columns.Add($colVZA) |

导入$filename时创建的表确实有名为VZA,VAZ等的列,因此不存在问题。

添加和填充列似乎应该是一项简单的任务,所以我确定我在这里遗漏了一些简单的东西。这是我的代码:

####################### 
function Get-Type 
{ 
    param($type) 

$types = @( 
'System.Boolean', 
'System.Byte[]', 
'System.Byte', 
'System.Char', 
'System.Datetime', 
'System.Decimal', 
'System.Double', 
'System.Guid', 
'System.Int16', 
'System.Int32', 
'System.Int64', 
'System.Single', 
'System.UInt16', 
'System.UInt32', 
'System.UInt64') 

    if ( $types -contains $type ) { 
        Write-Output "$type" 
    } 
    else { 
        Write-Output 'System.String' 

    } 
} #Get-Type 

####################### 
<# 
.SYNOPSIS 
Creates a DataTable for an object 
.DESCRIPTION 
Creates a DataTable based on an objects properties. 
.INPUTS 
Object 
    Any object can be piped to Out-DataTable 
.OUTPUTS 
   System.Data.DataTable 
.EXAMPLE 
$dt = Get-psdrive| Out-DataTable 
This example creates a DataTable from the properties of Get-psdrive and assigns output to $dt variable 
.NOTES 
Adapted from script by Marc van Orsouw see link 
Version History 
v1.0  - Chad Miller - Initial Release 
v1.1  - Chad Miller - Fixed Issue with Properties 
v1.2  - Chad Miller - Added setting column datatype by property as suggested by emp0 
v1.3  - Chad Miller - Corrected issue with setting datatype on empty properties 
v1.4  - Chad Miller - Corrected issue with DBNull 
v1.5  - Chad Miller - Updated example 
v1.6  - Chad Miller - Added column datatype logic with default to string 
v1.7 - Chad Miller - Fixed issue with IsArray 
.LINK 
http://thepowershellguy.com/blogs/posh/archive/2007/01/21/powershell-gui-scripblock-monitor-script.aspx 
#> 
function Out-DataTable 
{ 
    [CmdletBinding()] 
    param([Parameter(Position=0, Mandatory=$true, ValueFromPipeline = $true)] [PSObject[]]$InputObject) 

    Begin 
    { 
        $dt = new-object Data.datatable   
        $First = $true  
    } 
    Process 
    { 
        foreach ($object in $InputObject) 
        { 
            $DR = $DT.NewRow()   
            foreach($property in $object.PsObject.get_properties()) 
            {   
                if ($first) 
                {   
                    $Col =  new-object Data.DataColumn   
                    $Col.ColumnName = $property.Name.ToString()   
                    if ($property.value) 
                    { 
                        if ($property.value -isnot [System.DBNull]) { 
                            $Col.DataType = [System.Type]::GetType("$(Get-Type $property.TypeNameOfValue)") 
                         } 
                    } 
                    $DT.Columns.Add($Col) 
                }   
                if ($property.Gettype().IsArray) { 
                    $DR.Item($property.Name) =$property.value | ConvertTo-XML -AS String -NoTypeInformation -Depth 1 
                }   
               else { 
                    $DR.Item($property.Name) = $property.value 
                } 
            }   
            $DT.Rows.Add($DR)   
            $First = $false 
        } 
    }  

    End 
    { 
        Write-Output @(,($dt)) 
    } 


$i = 1


While ($i -le 211) {

#Set the variable to the filename with the iteration number
$filename = "c:\zMFM\z550Output\20dSummer\fixed20dSum550Output$i.csv"


#Check to see if that a file with $filename exists. If not, skip to the next iteration of $i. If so, run the code to collect the statistics for each variable and output them each to a different file
If (Test-Path $filename) {


#Calculate the Standard Deviation
#First get the average of the values in the column
$STDEVInputFile = Import-CSV $filename

#Find the average and count for column 'td'
$STDEVAVG = $STDEVInputFile | Measure-Object td -Average | Select Count, Average
$DevMath = 0

# Sum the squares of the differences between the mean and each value in the array
Foreach ($Y in $STDEVInputFile) {
$DevMath += [math]::pow(($Y.Average - $STDEVAVG.Average), 2)

#Divide by the number of samples minus one
$STDEV = [Math]::sqrt($DevMath / ($STDEVAVG.Count-1))

}

#Calculate the basic statistics for column 'td' with the MEASURE-OBJECT cmdlet
$STATS = Import-CSV $Filename |
Measure-Object td -ave -max -min |

#Export the statistics as a CSV
Export-CSV -notype "c:\zMFM\z550Output\20dSummer\tempstats$i.csv"


$GetColumns = Import-CSV $filename

#Append the standard deviation variable to the statistics table and add the value

$STATS2 = Import-CSV "c:\zMFM\z550Output\20dSummer\tempstats$i.csv" 

$StatsTable = Get-PSDrive | Out-DataTable

#$colSTDDEV = New-Object System.Data.DataColumn StdDev,([double])
$colVZA = New-Object System.Data.DataColumn VZA,([double])
#$colVAZ = New-Object System.Data.DataColumn VAZ,([double])


$colVZA = $GetColumns[0].VZA 
#$colVAZ = $GetColumns[0].VAZ #COMMENTED FOR DEBUGGING
#$colSTDDEV = $STDEV

#$StatsTable.Columns.Add($colSTDDEV) #COMMENTED FOR DEBUGGING
#$StatsTable[0].StdDev = $STDEV #COMMENTED FOR DEBUGGING


$StatsTable.Columns.Add($colVZA) |


#$StatsTable[0].VZA = $VZA 

#$StatsTable.Columns.Add($colVAZ) #COMMENTED FOR DEBUGGING
#$StatsTable[0].VZA = $VAZ #COMMENTED FOR DEBUGGING 

#Export the $STATS file containing everything you need in the correct folder



Export-CSV -notype "c:\zMFM\z550Output\20dSummer\20dSum550Statistics.csv"

}
$i++
}

1 个答案:

答案 0 :(得分:2)

即使$STATS2中的每个对象具有相同的属性,$STATS2对象本身也只是一个简单的数组,一个非结构化的对象列表 - 它没有Columns属性使用Add()方法:

$STATS2.Colums.Add($colVZA)
   ^       ^      ^
[array]    |      |
         $null    |
               this fails

您可以通过检查数组中第一个对象中的每个属性,将从Import-Csv获得的数组从数组转换为DataTable对象(具有列),例如{{3在technet脚本库