如何在数组/对象中转换我的值来测量它们?

时间:2014-09-24 09:49:14

标签: arrays powershell type-conversion measure

我是stackoverflow的新手,我并不是真正的PowerShell破解。也许你可以帮我解决我的问题。出于监控原因,我想从" vmstat 1 10"获得ssh结果。在Linux服务器上。我需要获得我拥有的10个值的Avarage值。通常" vmstat 1 10"结果如下:

procs -----------memory---------- ---swap-- -----io---- -system-- -----cpu------
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 1  0  42352 599980 315860 2488096    0    0  2606   794    5    2  3  0 94  2  0
 0  0  42352 600044 315860 2488096    0    0    64    84 1107 2107  0  1 99  1  0
 0  0  42352 596820 315860 2488096    0    0   280     4 1218 2179  7  1 91  2  0
 0  0  42352 589240 315860 2488096    0    0    32     7 1322 2366  1  1 95  3  0
 0  0  42352 588620 315860 2488096    0    0   144    37 1161 2181  1  0 96  3  0
 0  0  42352 588620 315860 2488096    0    0     0    24 1074 2075  0  0 100  0  0
 0  0  42352 588620 315860 2488096    0    0     0     0 1081 2081  0  1 100  0  0
 0  0  42352 588628 315860 2488096    0    0   128    32 1133 2091  1  0 96  3  0
 0  0  42352 588652 315860 2488100    0    0     0     0 1077 2058  0  0 100  0  0
 0  0  42352 588528 315860 2488100    0    0     0     5 1137 2147  0  0 99  0  0

因此,为了获得像swpd,free,buff等值的AVG,我的计划是在Object中获取整个值,然后制作类似$tab.swpd | Measure-Object -avg但我得到错误。

这是我在Script中获取值的脚本。 (我知道这不是很好 - 对不起。我还在学习......):

$runs = 10
#Get the Values via plink (putty)
$vmstat = .\plink.exe -ssh USER@SERVER -batch -pw "PASSWORD-YES-I-KNOW-THIS-IS-BAD" vmstat 1 $runs
$vmstat
##########################
#Get the Values in somthing like a csv
$vmstat = $vmstat.replace(" ", ";")
#replace alle double ";;" with single ";"
while ($vmstat -match ";;"){
    $vmstat = $vmstat.replace(";;", ";")
    }

#Delete ";" at the beginning (and at the end. Just to be sure. normally there arent ";" 's)
$vmstat = $vmstat.Trim(";")
#Save Columnames
$tabhead = $vmstat[1].split(";")
#Delete first and second row
$vmstat = $vmstat[2..($runs+1)]

##########################
#Split Values and Store it in an two-dimensional array
$values = New-Object system.Array[][] $tabhead.Length, $runs

for ($i=0;$i -lt ($vmstat.Length); $i++){
    $tmp = $vmstat[$i].split(";")

    for ($j=0;$j -lt ($tmp.Length); $j++){
        $values[$j][$i] = $tmp[$j]
        }
}

##########################
# Make an Object for Measurement!
$tab = New-Object System.Object

for ($i=0;$i -lt $tabhead.Length; $i++){
    $tab | Add-Member -type NoteProperty -name $tabhead[$i] -Value $values[$i]
}

所以在那之后我的所有值都像我想要的数组或对象。我可以选择我想看的值:

PS C:\> $tab

r     : {1, 0, 0, 0...}
b     : {0, 0, 0, 0...}
swpd  : {42352, 42352, 42352, 42352...}
free  : {599980, 600044, 596820, 589240...}
buff  : {315860, 315860, 315860, 315860...}
cache : {2488096, 2488096, 2488096, 2488096...}
si    : {0, 0, 0, 0...}
so    : {0, 0, 0, 0...}
bi    : {2606, 64, 280, 32...}
bo    : {794, 84, 4, 7...}
in    : {5, 1107, 1218, 1322...}
cs    : {2, 2107, 2179, 2366...}
us    : {3, 0, 7, 1...}
sy    : {0, 1, 1, 1...}
id    : {94, 99, 91, 95...}
wa    : {2, 1, 2, 3...}
st    : {0, 0, 0, 0...}

PS C:\> $tab.in
5
1107
1218
1322
1161
1074
1081
1133
1077
1137

但是,当我尝试类似:$tab.swpd | Measure-Object -Average时,我收到以下错误:

Measure-Object : Das Eingabeobjekt "System.Object[]" ist nicht numerisch.
In Zeile:1 Zeichen:13
+ $tab.swpd | Measure-Object -Average
+             ~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidType: (System.Object[]:Object[]) [Measure-Object], PSInvalidOperationException
    + FullyQualifiedErrorId : NonNumericInputObject,Microsoft.PowerShell.Commands.MeasureObjectCommand

我想我甚至不需要Object,我认为做$values[0] | Measure-Object -Average这样的事情也必须是可行的,但也有同样的错误。我知道问题是值不是int值。但我不知道如何转换它们以便我可以进行测量。

1 个答案:

答案 0 :(得分:-1)

我无法访问相同的资源,因此我无法完美地重现问题。你是对的。 Measure-Object试图告诉您它无法使用非数值。我认为PowerShell的新版本可以更好地处理这个问题,但是演员可能会对你做得很好。

[int[]]($tab.swpd) | Measure-Object -Average

这应该将System.Object[]数组投射到System.Int32[]

提高效率

您正在用分号分隔空白区域并将其合并,直到您拥有分号。正则表达式可能会保存整个循环。这将占用一组空白并将它们转换为分号。这可能会将您的问题保存到最后。这可能会解决您对Measure-Object的问题,因为这应该删除所有空格,假设您没有在其他地方添加任何其他空格。您仍然需要像现在这样处理由此创建的前导和尾随半冒号。

$vmstat = $vmstat.replace("\s+", ";")

根据评论进行修改

所以我看到演员表失败了。您的数组值中有空格,我最初没有注意到。也许这就是你拥有和发行的原因。你似乎有一个字符串数组。我将再次查看您的代码,并找出它们的来源。还有其他方法可以解决这个问题,但一个简单的方法可能是更新代码底部的这一行

$tab | Add-Member -type NoteProperty -name $tabhead[$i] -Value $values[$i].Trim()
相关问题