Powershell 当我将PS脚本存储在变量中时,为什么会得到不同的结果?
我制作了一个Powershell脚本,它在字符串数组上执行foreach并只收集其中的一些信息。 代码如下:Powershell 当我将PS脚本存储在变量中时,为什么会得到不同的结果?,powershell,powershell-4.0,Powershell,Powershell 4.0,我制作了一个Powershell脚本,它在字符串数组上执行foreach并只收集其中的一些信息。 代码如下: begin { $IMAGELIST = @( "IMAGE Srv01 something something something Srv01_999888777 something" "FRAG 1 something something" "FRAG 2 something something" ) } process { f
begin {
$IMAGELIST = @(
"IMAGE Srv01 something something something Srv01_999888777 something"
"FRAG 1 something something"
"FRAG 2 something something"
)
}
process {
foreach ($LINE in $IMAGELIST) {
if ($LINE.StartsWith("IMAGE")) {
$IMAGELINE = $LINE.split()
$BKP_OBJ = [pscustomobject]@{
Server=$IMAGELINE[1]
Id=$IMAGELINE[5]
}
}
elseif ($LINE.StartsWith("FRAG")) {
$FRAGLINE = $LINE.split()
$BKP_OBJ | Add-Member -Force @{
CopyNumber = $FRAGLINE[1]
}
Write-Output -InputObject $BKP_OBJ
}
}
}
运行脚本时,我有一个输出,其中有两个具有不同CopyNumber值的对象(预期结果):
如果我尝试将输出存储在变量中,我会得到相同的CopyNumber(不是预期的结果):
我做错了什么?我想你想要这样的东西
begin {
$BKP_OBJ = $null
$IMAGELIST = @(
"IMAGE Srv01 something something something Srv01_999888777 something",
"FRAG 1 something something",
"FRAG 2 something something"
)
}
process {
$Ximglist = @()
$Xfrglist = @()
foreach ($LINE in $IMAGELIST) {
if ($LINE.StartsWith("IMAGE")) {
$Ximglist += $LINE
}
elseif ($LINE.StartsWith("FRAG")) {
$Xfrglist += $LINE
}
}
foreach ($Ximg in $Ximglist) {
$Xfrglist | % {($_.split())[1]} | % {$BKP_OBJ = [pscustomobject]@{
Server= ($Ximg.Split())[1]
Id= ($Ximg.Split())[5]
CopyNumber=$_
};
Write-Output $BKP_OBJ}
}
}
只生成一个对象,修改并输出两次。赋值语句首先使其完成,然后再显示任何输出。指向两个输出的指针相同。(.\BkpScript)将执行相同的操作
cat myscript.ps1
$a = [pscustomobject]@{name='Joe'}
$a
$a.name = 'John'
$a
./myscript
name
----
Joe
John
(./myscript) # or ./myscript | sort
name
----
John
John
该代码将创建一个新对象,无论何时输出/管道:
begin {
$IMAGELIST = @(
"IMAGE Srv01 something something something Srv01_999888777 something"
"FRAG 1 something something"
"FRAG 2 something something"
)
}
process {
$Server = ""
$Id = ""
$CopyNumber = 0
foreach ($LINE in $IMAGELIST) {
if ($LINE.StartsWith("IMAGE")) {
$IMAGELINE = $LINE.split()
$Server=$IMAGELINE[1]
$Id=$IMAGELINE[5]
} elseif ($LINE.StartsWith("FRAG")) {
$FRAGLINE = $LINE.split()
$CopyNumber = $FRAGLINE[1]
Select-Object @{n='Server'; e={$Server}}, @{n='Id'; e={$Id}}, @{n='CopyNumber'; e={$CopyNumber}} -InputObject ''
}
}
}
输出看起来像您在问题中所期望的:
您可以将
$BKP\u OBJ
保存到一个变量(例如$ARR\u BKP\u OBJ
)中,以便以后使用。通过执行$ARR\u BKP\u OBJ=@()
和$ARR\u BKP\u OBJ+=$BKP\u OBJ
。我尝试先将$BKP\u OBJ添加到数组中,但是当我试图将脚本的输出存储到$MyVar变量时,我得到了同样的意外结果,认为图像和FRAG字符串是一组信息,在第二次中,我不能在两个单独的数组中进行处理,因为我可以有多个信息集。例如,“IMAGE Srv01 something something Srv01_99988777 something”FRAG 1 something“FRAG 2 something”IMAGE Srv02 something Srv02_456734231 something“FRAG 1 something”FRAG 2 something“FRAG 2 something”听起来像是要使用嵌套的foreach
?或者(像我的解决方案一样)在Foreach
语句中使用Foreach对象(=%
)。您能告诉我们一些有关您尝试使用此脚本解决的问题的更多信息吗?例如,它包含了很多东西来为管道化做好准备,但我不明白为什么。结果你想要什么?对象列表、字符串或仅在终端上输出?什么是$FRAGLINE
?您将它用作数组,但它是在哪里定义的?此外,如果第一次测试失败,将不会有对象添加CopyNumber
属性。问题的根本原因是,您在案例1中创建了一个对象,然后在案例2中对其进行更改,而不是复制它。因此,对象的所有“快照”都将是指向上次修改版本的指针。通常,$IMAGELIST是由外部命令输出提供的字符串数组。外部命令为每个唯一记录提供三行或更多行(第一行始终是IMAGE,其他行不止一个FRAG)对于每个唯一记录,我需要使用IMAGE string中的一些信息和FRAG string中的一些信息创建一个对象@托马斯:你说的话听起来很有道理,但我不能完全理解。在你看来,我应该如何改变剧本?@karnak请看下面我的答案。
cat myscript.ps1
$a = [pscustomobject]@{name='Joe'}
$a
$a.name = 'John'
$a
./myscript
name
----
Joe
John
(./myscript) # or ./myscript | sort
name
----
John
John
begin {
$IMAGELIST = @(
"IMAGE Srv01 something something something Srv01_999888777 something"
"FRAG 1 something something"
"FRAG 2 something something"
)
}
process {
$Server = ""
$Id = ""
$CopyNumber = 0
foreach ($LINE in $IMAGELIST) {
if ($LINE.StartsWith("IMAGE")) {
$IMAGELINE = $LINE.split()
$Server=$IMAGELINE[1]
$Id=$IMAGELINE[5]
} elseif ($LINE.StartsWith("FRAG")) {
$FRAGLINE = $LINE.split()
$CopyNumber = $FRAGLINE[1]
Select-Object @{n='Server'; e={$Server}}, @{n='Id'; e={$Id}}, @{n='CopyNumber'; e={$CopyNumber}} -InputObject ''
}
}
}
PS C:\Users\db\Desktop> .\test.ps1
Server Id CopyNumber
------ -- ----------
Srv01 Srv01_999888777 1
Srv01 Srv01_999888777 2
PS C:\Users\db\Desktop> $myvar = .\test.ps1
PS C:\Users\db\Desktop> $myvar
Server Id CopyNumber
------ -- ----------
Srv01 Srv01_999888777 1
Srv01 Srv01_999888777 2