2015-04-21 50 views
0

我正在嘗試創建一個用於還原備份的菜單。 理想情況下,用戶將看到一個文件夾列表,每個文件夾編號,然後提示選擇。列表和選擇選項需要是動態的。根據循環中的文件名創建數組

問題是我對循環和數組的理解有限。 這裏是我想與之合作的數組:

$saved_backups = Get-ChildItem $backup_folder |Where-Object {$_.Name -like "*$target_username"} | select-object @{n="Saved Backups:";e={$_.Name}} 
[array]::Reverse($saved_backups) 

從用戶的角度來說,我想它看起來像:

1) $saved_backups[0] 
2) $saved_backups[1] 

1) 2015.04.21_laptop 
2) 2015.04.20_laptop 

哪裏備份實際上是文件夾名稱。 然後用戶可以選擇編號並將選擇保存到我以後可以使用的變量中。

任何幫助表示讚賞!

編輯#1: 我能夠簡化與以下所需的文件夾名稱:

$saved_backups = Get-ChildItem $backup_folder |Where-Object {$_.Name -like "*$target_username"} 
[array]::Reverse($saved_backups) 
$saved_backups = $saved_backups.name 

編輯#2: 感謝馬特,我開始明白使用索引的想法。 現在的問題是我的數組,因爲它將兩個對象計數爲一個,然後對它計數兩次。

$saved_backups = Get-ChildItem $backup_folder |Where-Object {$_.Name -like "*$target_username"} 
[array]::Reverse($saved_backups) 
$saved_backups = $saved_backups.name 
For($folderIndex = 1; $folderIndex -le $saved_backups.Count; $folderIndex++){ 
Write-Host "[$folderIndex]$saved_backups" 
} 

電流輸出:

[1] Folder1 Folder2 
[2] Folder1 Folder2 

理想的情況下它會看起來像:

[1] Folder1 
[2] Folder2 

一旦我明白了聲明,我會選擇菜單上的工作。

+0

你只是在尋找一個循環,將數字條目?爲了獲得最大的價值,你可以包括你的選擇結構/代碼? – Matt

+0

是的,我不知道什麼類型的循環將允許每個找到的文件夾($ saved_backups)首先顯示一個計數,然後在數組中顯示相應的值。我需要選擇結構方面的幫助,但正計劃將其包含在循環中。 – semtex41

回答

0

終於學到了。我的問題是將循環應用於變量中的每個對象,然後確定我需要將counter/$索引放在循環之外。生活是艱難的,但如果你的愚蠢更難。 = d

$saved_backups = Get-ChildItem $backup_folder |Where-Object {$_.Name -like "*$target_username"} 
[array]::Reverse($saved_backups) 
$saved_backups = $saved_backups.name 

#This is my answer. The Counter/$Index outside the Loop. 
$index = 0 
foreach ($element in $saved_backups) { 
$index++ 
Write-Host "[$index]$element" 
} 

輸出:

[1] Folder1 
[2] Folder2 

PS - 馬特將盡快得到一個給予好評,因爲我有百分點。感謝您的幫助。

1

我剛把它弄出來,它使用choice代碼。

$backupLocations = get-childitem c:\temp -filter '*data*' | Where-Object{$_.PSIsContainer} 

$title = "Backups" 
$message = "Please choose a backup location" 
$backupLocations.count 
$selections = @() 
For($folderIndex = 1; $folderIndex -le $backupLocations.Count; $folderIndex++){ 
    $selections += New-Object System.Management.Automation.Host.ChoiceDescription "&$folderIndex- $($backupLocations[$folderIndex -1].Name)", $backupLocations[$folderIndex -1].FullName 
} 
$options = [System.Management.Automation.Host.ChoiceDescription[]]($selections) 
$result = $host.ui.PromptForChoice($title, $message, $options, 0) 


$backupLocations[$result].FullName 

它將提示用戶選擇由上述代碼所定義的選擇。在交互模式下,提示符將如下所示。 Data和Data2是文件夾名稱。

Choice

如果您的實際問題發揮作用是循環的文件夾和編號他們。我將關注這一點。因此我們使用索引來遍歷數組。這個指數只是用來讓我們可以隨心所欲。對於每個確定的文件夾,我們創建一個選擇或選擇對象。該對象有一個標題和說明。 &符將號碼與選擇相關聯,以便用戶可以將其選擇爲快捷方式。在上圖中,您會注意到數字下方的下劃線。

FYI

關於第二個編輯你接近。 $saved_backups本身就是一個數組,你也可以索引它。如果您注意到這是我在代碼示例中所做的。

For($folderIndex = 1; $folderIndex -le $saved_backups.Count; $folderIndex++){ 
Write-Host "[$folderIndex]$($saved_backups[$folderIndex-1])" 
} 

之前發生了什麼事是$saved_backups整個列表正在轉換爲字符串,以便它可以輸出這就是爲什麼你看到的重複。

+0

非常有幫助,謝謝!我能夠使用文件夾索引的想法,並把它關閉。我將堅持這個迭代的CLI菜單。仍然有問題與兩次folderindex計數,而不是每個獲得一個數字,一切都被計算兩次。我會用我當前的代碼做第二次編輯。 – semtex41

+0

@ semtex41看看我的小小更新。 – Matt

1

我覺得有必要編鐘。我保留一個函數來生成文本菜單,所以我在這裏發佈它以防萬一您需要。

Function MenuMaker{ 
    param(
     [parameter(Mandatory=$true, 
     ValueFromPipeline = $true)][String[]]$Selections, 
     [string]$Title = $null 
     ) 

    $Width = if($Title){$Length = $Title.Length;$Length2 = $Selections|%{$_.length}|Sort -Descending|Select -First 1;$Length2,$Length|Sort -Descending|Select -First 1}else{$Selections|%{$_.length}|Sort -Descending|Select -First 1} 
    $Buffer = if(($Width*1.5) -gt 78){[math]::floor((78-$width)/2)}else{[math]::floor($width/4)} 
    if($Buffer -gt 6){$Buffer = 6} 
    $MaxWidth = $Buffer*2+$Width+$($Selections.count).length+2 
    $Menu = @() 
    $Menu += "╔"+"═"*$maxwidth+"╗" 
    if($Title){ 
     $Menu += "║"+" "*[Math]::Floor(($maxwidth-$title.Length)/2)+$Title+" "*[Math]::Ceiling(($maxwidth-$title.Length)/2)+"║" 
     $Menu += "╟"+"─"*$maxwidth+"╢" 
    } 
    For($i=1;$i -le $Selections.count;$i++){ 
     $Item = "$(if ($Selections.count -gt 9 -and $i -lt 10){" "})$i`. " 
     $Menu += "║"+" "*$Buffer+$Item+$Selections[$i-1]+" "*($MaxWidth-$Buffer-$Item.Length-$Selections[$i-1].Length)+"║" 
    } 
    $Menu += "╚"+"═"*$maxwidth+"╝" 
    $menu 
} 

然後,無論是給它一個數組或給它一個數組和標題。

$Saved_Backups = @("2015.04.21_laptop","2015.04.20_laptop") 
menumaker $Saved_Backups 
╔════════════════════════════╗ 
║ 1. 2015.04.21_laptop ║ 
║ 2. 2015.04.20_laptop ║ 
╚════════════════════════════╝ 

或者,添加標題...

menumaker $Saved_Backups -Title "Select a backup to restore" 
╔═════════════════════════════════════════╗ 
║  Select a backup to restore  ║ 
╟─────────────────────────────────────────╢ 
║  1. 2015.04.21_laptop    ║ 
║  2. 2015.04.20_laptop    ║ 
╚═════════════════════════════════════════╝ 

想要漂亮,並添加選擇驗證?

$saved_backups = Get-ChildItem $backup_folder |Where-Object {$_.Name -like "*$target_username"} | select-object @{n="Saved Backups:";e={$_.Name}} 
[array]::Reverse($saved_backups) 
$Options = [Ordered]@{} 
$BkUpCnt = 1 
$saved_backups | ForEach{$Options.Add($BkUpCnt,$_);$BkUpCnt++} 
Do{ 
    menumaker $saved_backups -Title "Select a backup" 
    If(!([string]::IsNullOrEmpty($Selection)) -and $Selection -notin $Options.keys){Write-Host "`nNot a valid selection, please try again.`n" -ForegroundColor Red} 
    $Selection = Read-Host "Backup selection"} 
While(([string]::IsNullOrWhiteSpace($Selection)) -or $Selection -notin $Options.keys) 
$SelectedBackup = $Options[($Selection - 1)] 

顯示的菜單,提示他們的選擇,可以確保他們選擇的是一個有效的選擇,如果沒有再顯示在一個錯誤,表明他們沒有選擇正確的選項添加。