Powershell5 Компактный код, объединяющий команды foreach, begin, process и replace - PullRequest
0 голосов
/ 19 февраля 2019

Могу ли я получить те же результаты с меньшим количеством кода?Код ищет в файле sample.bat строки AROUND LINE {1-9999} и LINE2 {1-9999} и заменяет {1-9999} на {номер строки}, в котором включен код.

sample.bat:

AROUND LINE 262
LINE2 1964

Старый код:

gc $env:temp\sample.bat | foreach -Begin {$lc = 1} -Process {
  $_ -replace "AROUND LINE \d*", "AROUND LINE $lc";
  $lc += 1
} | Out-File -Encoding Ascii $env:temp\results.bat
(gc $env:temp\results.bat) | foreach -Begin {$lc = 1} -Process {
  $_ -replace "LINE2 \d*", "LINE2 $lc";
  $lc += 1
} | Out-File -Encoding Ascii $env:temp\results.bat

Текущий код:

(gc $env:temp\sample.bat) | foreach -Begin {$lc = 1} -Process {
  $_ -replace "AROUND LINE \d*", "AROUND LINE $lc";
  $lc += 1
} | foreach -Begin {$lc = 1} -Process {
  $_ -replace "LINE2 \d*", "LINE2 $lc";
} | Out-File -Encoding Ascii $env:temp\sample.bat

Ожидаемые результаты:

AROUND LINE 1
LINE2 2

Фактические результаты:

AROUND LINE 1
LINE2 2

1 Ответ

0 голосов
/ 19 февраля 2019

Вы можете сделать эту работу с одним регулярным выражением:

gc $env:temp\sample.bat | foreach -Begin {$lc = 1} -Process {
  $_ -replace '(?<=AROUND LINE |LINE2 )\d+', $lc++
} | Set-Content -Encoding Ascii $env:temp\results.bat

Обратите внимание, что я использую '...' (одинарные кавычки) вместо "..." (двойные кавычки) для включениярегулярное выражение, которое предпочтительно исключает возможную путаницу, возникающую из-за того, что PowerShell сначала выполняет расширение (интерполяцию) строки.
$lc++ возвращает текущее значение $lc, а затем увеличивает его на 1, устраняя необходимость в $lc += 1 оператор.
Кроме того, я заменил Out-File на Set-Content, так как они функционально одинаковы для сохранения строк , но последний быстрее.
Наконец, чтобы соответствовать одна или несколько цифр , используйте \d+ вместо \d*.

Примечание к $_ -replace '(?<=AROUND LINE |LINE2 )\d+', $lc++:

  • Regex(?<=AROUND LINE |LINE2 )\d+ использует проверочное утверждение ((?<=...) для поиска (|) строки AROUND LINE или строки LINE2 перед одной или несколькими (+) цифрами (\d).

    • Утверждаемое утверждение по своей конструкции не считается частью совпадения, поэтому подстрока получает заменуd ограничен набором цифр, т. е. только число .
  • $lc++ - операнд замены: он возвращает текущее значениепеременная $lc и увеличивает ее значение впоследствии ;обратите внимание, что хотя $lc является числом ([int]), PowerShell автоматически преобразует его в строку для замены.


Как правило,тем не менее, вы можете просто цепочка -replace операции:

# ...
$_ -replace 'AROUND LINE \d+', "AROUND LINE $lc" -replace 'LINE2 \d+', "LINE2 $lc"
++$lc
# ... 
...