将PowerShell中返回的字符串转换为分隔数据并导出

时间:2015-10-14 16:00:10

标签: powershell

我使用PowerShell远程配置来自不同供应商的存储阵列。该脚本允许我连接到阵列没有问题。从那里我使用REST API调用或通过plink.exe远程SSH运行命令。这是我的问题。使用plink时,我需要查询数组,然后根据输出有条件地执行操作。问题是输出以字符串格式返回。这对我来说是一个问题,因为我想对返回的字符串的部分进行排序和提取,并根据输出向用户提供选项。

示例 - 列出卷

if ($sel_vendor -eq 3){ $ibm_ex_vols = & $rem_ssh $rem_ssh_arg1 $rem_ssh_arg2 $array_user"@"$array_mgmt_ip "-pw" $readpass "lsvdisk" foreach ($i in $ibm_ex_vols){ write-host $i } }

以下是代码的输出

id name  IO_group_id IO_group_name status mdisk_grp_id mdisk_grp_name  capacity type    FC_id FC_name RC_id RC_name vdisk_UID                        fc_map_count copy_count fast_write_state se_copy_count RC_change compressed_copy_count parent_mdisk_grp_id parent_mdisk_grp_name
0  Test1 0           io_grp0       online 0            SVC_SYSTEM_POOL 10.00GB  striped                             600507680C80004E980000000000074B 0            1          empty            1             no        0                     0                   SVC_SYSTEM_POOL
1  Test2 0           io_grp0       online 0            SVC_SYSTEM_POOL 10.00GB  striped                             600507680C80004E980000000000074C 0            1          empty            1             no        0                     0                   SVC_SYSTEM_POOL
2  Test3 0           io_grp0       online 0            SVC_SYSTEM_POOL 10.00GB  striped                             600507680C80004E980000000000074D 0            1          empty            1             no        0                     0                   SVC_SYSTEM_POOL
3  Test4 0           io_grp0       online 0            SVC_SYSTEM_POOL 10.00GB  striped                             600507680C80004E980000000000074E 0            1          empty            1             no        0                     0                   SVC_SYSTEM_POOL

我希望能够存储此信息,然后从id和name列中选择标题和数据。我可以使用out-file命令将数据输出到txt文件。一旦我这样做,我使用Excel使用fixed with delimiter选项将其转换为分隔文件。虽然这很有效,但我需要找出一个动态的解决方案。

2 个答案:

答案 0 :(得分:2)

这是一个简单的解析函数,它可以分割您的数据并生成具有要使用的属性的自定义对象:

function Parse-Data{
    begin{
        $Headers=$null
    }
    process{
        if(!$Headers){
            $Headers=
            [Regex]::Matches($_,'\S+')|
            ForEach-Object {
                $Header=$null
            } {
                if($Header){
                    $Header.SubArgs+=$_.Index-1-$Header.SubArgs[0]
                    $Header
                }
                $Header=[PSCustomObject]@{
                    Name=$_.Value
                    SubArgs=,$_.Index
                }
            } {
                $Header
            }
        }else{
            $String=$_
            $Headers|
            ForEach-Object {
                $Object=[ordered]@{}
            } {
                $Object.Add($_.Name,$String.Substring.Invoke($_.SubArgs).TrimEnd())
            } {
                [PSCustomObject]$Object
            }
        }
    }
}

这就是你如何调用它:

$ibm_ex_vols=@'
id name  IO_group_id IO_group_name status mdisk_grp_id mdisk_grp_name  capacity type    FC_id FC_name RC_id RC_name vdisk_UID                        fc_map_count copy_count fast_write_state se_copy_count RC_change compressed_copy_count parent_mdisk_grp_id parent_mdisk_grp_name
0  Test1 0           io_grp0       online 0            SVC_SYSTEM_POOL 10.00GB  striped                             600507680C80004E980000000000074B 0            1          empty            1             no        0                     0                   SVC_SYSTEM_POOL
1  Test2 0           io_grp0       online 0            SVC_SYSTEM_POOL 10.00GB  striped                             600507680C80004E980000000000074C 0            1          empty            1             no        0                     0                   SVC_SYSTEM_POOL
2  Test3 0           io_grp0       online 0            SVC_SYSTEM_POOL 10.00GB  striped                             600507680C80004E980000000000074D 0            1          empty            1             no        0                     0                   SVC_SYSTEM_POOL
3  Test4 0           io_grp0       online 0            SVC_SYSTEM_POOL 10.00GB  striped                             600507680C80004E980000000000074E 0            1          empty            1             no        0                     0                   SVC_SYSTEM_POOL
'@-split'\r?\n'

$ibm_ex_vols|Parse-Data

答案 1 :(得分:1)

这是一个更简单,基于数学的解决方案(假设$ibm_ex_vols包含输出作为字符串集合):

$sOutFile = "outfile.csv"

# Splitting the headers line into chars.
$cChars = $ibm_ex_vols[0] -split ''

$cInsertIndices = @()
$j = 0
for ($i = 1; $i -lt $cChars.Count; $i++) {
    # If previous character is a whitespace and the current character isn't
    if ( ($cChars[$i - 1] -eq ' ') -and ($cChars[$i] -ne  ' ') ) {
        # we'll insert a delimiter here
        $cInsertIndices += $i + $j - 1
        $j++ # and each insert will increase the line length.
    }
}

foreach ($sLine in $ibm_ex_vols) {
    foreach ($i in $cInsertIndices) {
        # Adding delimiter.
        $sLine = $sLine.Insert($i, ',')
    }

    # Optionally we can also trim trailing whitespaces:
    # $sLine = $sLine -replace '\s+(?=,)'
    $sLine | Out-File -FilePath $sOutFile -Append
}

当然,这里我们不进行任何实际的解析,因此无法使用方便的PSObjects。

最后,如果我们可以确定所有数据字段都将被填充并且不包含任何空白字符,我们就不需要依赖字段宽度,并且可以进一步简化我们的代码:

$sOutFile = "outfile.csv"

foreach ($sLine in $ibm_ex_vols) {
    $sLine = $sLine -replace '\s+', ','
    $sLine | Out-File -FilePath $sOutFile -Append
}