2017-02-21 5 views
0

Я struggeling с следующей ситуацией:петля Еогеасп смешивает результат

testfile.txt

1 a 
2 b 
3 c

Сценарий:

$input = Get-Content "C:\Scripts\testfile.txt" 

foreach ($line in $input) { 
    $var1 = $line.Substring(2,1) 
    $output = "$var1 is $var2" 

    if ($line -match "1") { 
     $var2 = "1" 
     Write-Host $output 
    } elseif ($line -match "2") { 
     $var2 = "2" 
     Write-Host $output 
    } elseif ($line -match "3") { 
     $var2 = "3" 
     Write-Host $output 
    } else {} 
} 

Результат:

a is 3 
b is 1 
c is 2

Почему результат перепутан? Оно должно быть:

a is 1 
b is 2 
c is 3

Даже если я поставил $output в конце цикла foreach ?!

+3

Переместить '$ output =" $ var1 равно $ var2 "' перед 'Write-Host', поскольку это не шаблон, а сразу же expa которая использует предыдущие значения. – wOxxOm

+0

Конечно, тогда он будет работать. Но действительно ли нужно вставлять его в каждое утверждение if? –

+1

Или вы можете изменить каждый Write-Host на «Write-Host» $ var1 is $ var2 «' –

ответ

4

Вы, вероятно, запускали код, прежде чем, потому что обычно результат должен выглядеть следующим образом:

a is 
b is 1 
c is 2

В 3 в первой строке вывода, очевидно, сохраняется от предыдущей попытки.

Причиной такого поведения является то, что вы только присвоить значение $var2после присвоить "$var1 is $var2" переменной. Переменные в строке уже расширены при назначении, поэтому вы получите значение $var2 из предыдущей итерации (или пустого значения при первом запуске).

Чтобы получить вывод, который вы хотите изменить свой код на этот:

foreach ($line in $input) { 
    $var1 = $line.Substring(2,1) 
    $output = "$var1 is {0}" 

    if ($line -match '1') { 
     Write-Host ($output -f '1') 
    } elseif ($line -match '2') { 
     Write-Host ($output -f '2') 
    } elseif ($line -match '3') { 
     Write-Host ($output -f '3') 
    } 
} 

или как это:

foreach ($line in $input) { 
    $var1 = $line.Substring(2,1) 

    $var2 = if ($line -match '1') { 
     '1' 
    } elseif ($line -match '2') { 
     '2' 
    } elseif ($line -match '3') { 
     '3' 
    } 

    if ($var2) { 
     Write-Host "$var1 is $var2" 
    } 
} 

еще лучше, так как вы используете регулярное выражение матч во всяком случае, сделать что-то например:

foreach ($line in $input) { 
    $var1 = $line.Substring(2,1) 

    if ($line -match '[1-3]') { 
     Write-Host "$var1 is $($matches[0])" 
    } 
} 
Смежные вопросы