2017-02-13 22 views
0

私は現在、ユーザーを支援する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の出力は常に同じままです。

foreachに変更を反映させるには、どうすれば$textfileを更新して反映させることができますか?

答えて

3

あなたが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 
0

実際に$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 
2

foreach文の$string変数は、コレクション内の「現在」の項目を参照するが、それはコピーではなく、元のコレクションへの参照です。

新しい配列を作るか、それForEach-Objectコマンドレットでパイプラインを作る必要があります。

$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 

あなたの正規表現のものでも不必要に複雑です。あなただけの一致する部分を参照するために後方参照を使用して、交換するかすることができ、とても全部はこれをさらに簡素化することができる:

-replaceは、配列上で動作することができますので、あなたは、もはや ForEach-Objectを必要とする、ことを行わなかった
$textfile | ForEach-Object -Process { 
    $_ -replace '(EC\d*=)', "`${1}$pulse," 
} | out-file -filepath C:\new_file.jbi 

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

私はこの2番目の例を動作させることはできません。 $ -lplace '(EC \ d * =)'、 '' $ 1 $ pulse ''を動作させることはできますが、$ pulseが数字で始まると失敗します。また、Out-Fileを追加したり、Add-Contentのために交換したりする必要があると思います。 – mjolinor

+0

@mjolinorあなたが正しいと思うので、コードを更新して、逆参照で正しく動作するようにしましたが、この場合は追加したくないと思います。 'ForEach-Object'呼び出しの出力はすべてOut-Fileにパイプされるので、何かが見つからない限り完全な内容を含みます。 – briantist

+0

あなたは-appendに関して正しいですが、私はまだそれがバグの可能性を置き換えると考えています。また、Foreachは本当に必要ではありません。 -Replaceは配列演算子として機能します。 – mjolinor

関連する問題