powershell foreach - 对阵列项的更改不更新阵列

问题描述:

我目前正在编写一个PowerShell脚本来帮助用户。powershell foreach - 对阵列项的更改不更新阵列

我正在读取由程序生成的文件,并将其写入array

我用foreach遍历它,并根据需要进行更改。

然后,我想将文本(包括更改)写入新文件。

Param(
    [Parameter(Mandatory=$true, Position=0, HelpMessage="pulse?")] 
    [string]$pulse, 

    [Parameter(Mandatory=$true, Position=1, HelpMessage="milimeter?")] 
    [string]$milimeter 
) 

$textfile = Get-Content C:\11111_O.jbi 

foreach($string in $textfile) { 

    $string -match '(EC\d*=)' 

    if($matches) { 
     [string]$regex = $matches[1] 
     [string]$replacement = ($regex + $pulse + ',') 
     $string = $string -replace '(EC\d*=)', "$replacement" 
    } 
} 

$textfile | Out-File -FilePath C:\new_file.jbi 

但是,即使我已经检查了代码foreach多次(它做什么,它应该做的$string)内。 $textfile的输出始终保持不变。

我该如何获得$textfile以更新并反映我在foreach中对其所做的更改?

因为你使用foreach,你会得到各行的副本到$string变量 - 这是你在每次迭代修改什么,这样的$textfile本身的内容从未改变。

您可以只使用一个for循环,而不是:

for ($i = 0; $i -lt $textfile.count; $i++) { 
    $textfile[$i] -match '(EC\d*=)' 
    if($matches) { 
    [string]$regex = $matches[1] 
    [string]$replacement = ($regex + $pulse + ',') 
    $textfile[$i] = $textfile[$i] -replace '(EC\d*=)', "$replacement" 
    } 
} 

$textfile | out-file -filepath C:\new_file.jbi 

如果您确实需要更新$textfile,则需要使用for循环,但是如果只是输出到文件,则不需要操作该数组,您可以直接将操作内容转储到文件。

foreach($string in $textfile) { 
    $string -match '(EC\d*=)' 
    if($matches) { 
    [string]$regex = $matches[1] 
    [string]$replacement = ($regex + $pulse + ',') 
    $string -replace '(EC\d*=)', "$replacement" 
    } 
} | out-file -filepath C:\new_file.jbi 

foreach语句$string变量是指集合中的“当前”的项目,但它是一个副本,而不是原来的集合的引用。

你应该做一个新的阵列或使其与ForEach-Object cmdlet的管道:

$textfile | ForEach-Object -Process { 
    $string = $_ 
    if($string -match '(EC\d*=)') 
    { 
     [string]$regex = $matches[1] 
     [string]$replacement = ($regex + $pulse + ',') 
     $string = $string -replace '(EC\d*=)', "$replacement" 
    } 
    $string  
} | out-file -filepath C:\new_file.jbi 

你的正则表达式的东西也过于复杂。你可以做的更换,使用反向引用来引用匹配的部分,所以整个事情可以进一步简化为这样:

$textfile | ForEach-Object -Process { 
    $_ -replace '(EC\d*=)', "`${1}$pulse," 
} | out-file -filepath C:\new_file.jbi 

已经这样做了,你不再需要ForEach-Object因为-replace可以在阵列工作:

$textfile -replace '(EC\d*=)', "`${1}$pulse," | 
    out-file -filepath C:\new_file.jbi 
+0

我不能得到第二个例子的工作。我可以得到'替换'(EC \ d * =)','$ 1 $ pulse',但是如果$ pulse以数字开头,它会失败。另外,我认为你需要在该Out-File上使用一个--append,或者为Add-Content进行交易。 – mjolinor

+0

@mjolinor你是对的,我更新了代码,使其能够正确地与反向引用一起工作,但我不认为你会想在这种情况下追加。 “ForEach-Object”调用的输出将全部输入到“Out-File”中,因此它将包含完整内容,除非我错过了某些内容。 – briantist

+0

你对--append是正确的,但我仍然会考虑替换潜在的错误。另外,Foreach并不是真的有必要。 -Replace将作为数组运算符工作。 – mjolinor