【问题标题】:How do I automaticaly create and use variable names?如何自动创建和使用变量名?
【发布时间】:2023-03-08 17:13:01
【问题描述】:

我有 10 个变量,称为 rows($row1, $row2, $row3...),我需要用户从其中一个变量中进行选择,只知道正确的行,我很难理解如何连接文本到一个变量,对应另一个变量并获取值,而不是写成文本

$ChoosenRow = Read-Host
$rownumber = $("row" + $ChoosenRow)
$IP = Write-Output $rownumber 

如果我输入 10,我会得到 $IP = row10 我试图让 $IP 成为 $row10 的值,而不是字符串。

对不起,我的英语不好和我的愚蠢问题,我试图搜索类似的问题,但没有找到任何

编辑:iRon 让我添加更多脚本:

# Carica il file e crea le variabili per il file
$FilePath = '\\ntced\CED\AssistenzaPC\IP IN GESTIONE\2021-08-16 TabellaIP.xls'
$xl = New-Object -ComObject Excel.Application
$xl.Visible = $true
$wb = $xl.Workbooks.Open($filepath)

# Prendi la prima colonna
$data = $wb.Worksheets['Foglio1'].UsedRange.Rows.Columns[1].Value2
$data2 = $wb.Worksheets['Foglio1'].UsedRange.Rows.Columns[2].Value2

# Chiudi excel aperto per prendere i dati
$wb.close()
$xl.Quit()
While([System.Runtime.Interopservices.Marshal]::ReleaseComObject($wb) -ge 0){}
while([System.Runtime.Interopservices.Marshal]::ReleaseComObject($xl) -ge 0){} 
Remove-Variable xl,wb # Rimuovi le due variabili create

# display results
$data | select -skip 1 # Rimuove il titolo sopra

# Variabili degli IP

$variables = @()
$i = 0
foreach ($row in ($data -split [Environment]::NewLine)) {
  # Crea una variabile per ogni riga
  New-Variable -Name "row$i" -Value $row
  # e un membro dell'array
  $variables += [pscustomobject]@{Name = "row$i"; Value = $row} # Copiato male, era troppo complicato arrivarci
  $i++
}

$variables2 = @()
$ii = 0
foreach ($linea in ($data2 -split [Environment]::NewLine)) {
  # Crea una variabile per ogni riga
  New-Variable -Name "linea$ii" -Value $linea
  # e un membro dell'array
  $variables2 += [pscustomobject]@{Name = "linea$ii"; Value = $linea} 
  $ii++
}

function Show-Menu
{
 param (
 [string]$Title = 'Scegli IP'
 )
 Clear-Host
 Write-Host "================ $Title ================"
 Write-Host "1: Cambia IP da tabella IP nuovi"
 Write-Host "Q: premi 'Q' per uscire."
}

Show-Menu –Title 'Scegli IP'
$selection = Read-Host 'Scegli la'

switch ($selection)
 {
     '1' {
         ' Scrivi la linea che contiene IP libero'

         $LineaScelta = Read-Host
         $rownumber = $("row" + $LineaScelta)

          $IP = Write-Output $rownumber
          $MaskBits = 20 # subnet mask in bits = 255.255.240.0
          $Gateway = "172.16.111.254"
          $Dns = "172.16.16.1"
          $IPType = "IPv4"
     } 

     'q' { 
           return
         }
 }

  # Imposta su tutte le schede di rete attive, quindi tenere acceso solo quella necessaria!
$adapter = Get-NetAdapter | ? {$_.Status -eq "up"}

# Rimuove gli IP prima di metterli 
If (($adapter | Get-NetIPConfiguration).IPv4Address.IPAddress) {
 $adapter | Remove-NetIPAddress -AddressFamily $IPType -Confirm:$false
}

If (($adapter | Get-NetIPConfiguration).Ipv4DefaultGateway) {
 $adapter | Remove-NetRoute -AddressFamily $IPType -Confirm:$false
}

 # Configura gli IP, CHE BESTEMMIE PER CAPIRE COME USARE

$adapter | New-NetIPAddress `
 -AddressFamily $IPType `
 -IPAddress $IP `
 -PrefixLength $MaskBits `
 -DefaultGateway $Gateway

# Configura il primo server DNS, non so come configurare il secondo ancora.
$adapter | Set-DnsClientServerAddress -ServerAddresses $DNS




【问题讨论】:

  • 这能回答你的问题吗? PowerShell - Merge two variables into one
  • ...或者您的意思是像查找表这样的东西?
  • 别担心你的英语,它已经足够好了。无论如何,也许您需要一个数组并使用输入来索引它,或者使用 switch 语句。请edit问题并用简单的英语详细说明您想做什么,以便我们提出适当的解决方案。
  • 如果我理解正确的话,我想你应该和Get-Variable玩一玩
  • 请尝试创建minimal reproducible example 并向我们展示(在问题中)您是如何确切创建“我有 10 个变量,称为 rows($row1, $row2, $row3...)"。请注意,您很可能开始错误,而不是创建 10 个单独的变量(和 Get-Variable 这绝对是一个不好的做法),您可能想要创建一个数组(或 hashtable)然后使用:$Rows[10] 之类的东西。

标签: powershell


【解决方案1】:

一般(最佳实践)建议:

不要将<verb>-Variable cmdlets 用于动态变量名!

(Rule request: #1706 Warning if Set/Get-Variable is invoked with only the basic -Name/-Value parameters.)

背景

PowerShell(与几乎所有其他编程语言一样)有一个内部字典,它保留所有变量名称和对其包含值的(直接或间接)引用。字典基于binary search algorithm,以便能够快速找到与具体变量名相关的值。

为什么不呢?

为特定值创建任何(唯一)变量名称是一种通用用法,但此时您发现您的程序不再是 DRY 并开始使用使用 @ 的语句自动执行变量名称本身987654333@,如:New-Variable -Name "row$i" -Value $row,您可能会失去疏忽甚至与其他变量名发生冲突。相反,您最好使用hashtable(也基于二进制搜索)创建自己的自定义字典。

怎么做?

而不是这个:

$variables = @()
$i = 0
foreach ($row in ($data -split [Environment]::NewLine)) {
  # Crea una variabile per ogni riga
  New-Variable -Name "row$i" -Value $row
  # e un membro dell'array
  $variables += [pscustomobject]@{Name = "row$i"; Value = $row} # Copiato male, era troppo complicato arrivarci
  $i++
}

你可以这样做:

$Rows = @{}
$i = 0
foreach ($row in ($data -split [Environment]::NewLine)) { $Rows[$i++] = $Row }

并获取具体值:

$LineaScelta = Read-Host
$IP = $Rows[[Int]$LineaScelta]

由于字典的键似乎是一个连续的从零开始的数字系列,您甚至可以使用数组进一步简化它:

$Rows = $data -split [Environment]::NewLine

$LineaScelta = Read-Host
$IP = $Rows[$LineaScelta]

作为侧节点:也是try I avoid using the increase assignment operator (+=) to create a collection

【讨论】:

  • 这太棒了,首先你让代码变得更快、更干净 + 解决了我的问题,并在短短几行代码中教会了我很多东西......我头疼了 3 天...... .. 非常感谢!
  • @Kitsu 这是一个很好的例子,为什么在问题中包含背景信息和细节是个好主意。当我们了解实际情况时,提供帮助会容易得多。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-23
  • 2019-07-25
  • 2021-10-26
相关资源
最近更新 更多