2015-10-14 52 views
1

我正在使用PowerShell遠程配置來自各個供應商的存儲陣列。該腳本允許我連接到沒有問題的陣列。從那裏我通過plink.exe使用REST API調用或遠程SSH運行命令。這是我的問題。當使用plink時,我需要查詢數組,然後根據輸出條件執行操作。問題是輸出以字符串格式返回。這對我造成了一個問題,因爲我想對返回的字符串進行排序並提取部分內容,並根據輸出向用戶提供選項。將PowerShell中的返回字符串轉換爲分隔數據並導出

示例 - 列出卷

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將其轉換爲使用帶有分隔符選項的固定分隔文件。雖然這工作,我需要找出一個動態的解決方案。

+2

由於列的寬度將改變取決於各種值有多長(例如具有長名稱使名稱列比平常更長的系統),我會做的是執行一個正則表達式匹配捕獲每個頭文件列表幷包含空格,然後使用頭文件的長度構造一個寬度分隔的正則表達式匹配,可將每行分解爲PSCustomObjec t與值,你會被設置爲導出爲CSV或做任何你想要的。 – TheMadTechnician

回答

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 
      } 
     } 
    } 
} 

這是你可以調用它:

[email protected]' 
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 
+0

您將數據封裝在@'和'@中。在我的代碼中,這不是一個靜態的信息塊。這是一個存儲在$ ibm_ex_vols中的字符串。我可以簡單地用這個替換文本: @'$ ibm_ex_vols'@ –

+1

@SteveKehrer您可以在這裏使用變量。我做了一個編輯。 – PetSerAl

+0

這很好,但我希望只有id和名稱列的縮寫輸出。 –

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 
} 
+1

這裏有一些基於你的想法的oneliner:'$ ibm_ex_vols-replace'(?<= ^($(([Regex] :: Matches($ ibm_ex_vols [0],'\ S')。 $ _}「}) - join'|')))」,',''。 – PetSerAl

+0

所以這是獲取逗號分隔輸出的一個很好的簡短方法。結果是它將輸出打印到屏幕上,這不是我拍攝的內容。我真正需要的是能夠接收該字符串並解析出ID和名稱頭和值,並理想地顯示在表中。如果我可以將數據導出到CSV,導入然後使用select-object,我可以輕鬆完成此操作。如果可能,我希望避免進口出口路線。 –

+0

@PetSerAl很好的一個。看起來像一個Perl黑客雖然。 ;)我認爲保留一些可讀性是更實際的,即使以一些額外的代價爲代價。 –

相關問題