PowerShell имеет нет sed
-подобных конструкций для обработки диапазонов строк (например, sed
интерпретирует 1,/foo/
как ссылку на диапазон последовательных строк от строки 1 до следующей строки, которая соответствует регулярное выражение foo
)
Эмуляция этой функции с построчной обработкой была бы намного более многословной , но сравнительно более краткая версия возможна, если входной файл обрабатывается в целом - это вариант только с файлами, достаточно маленькими, чтобы поместиться в память в целом (PSv5 + синтаксис).
Вот чистый код PowerShell:
$escapedTimeStamp = [regex]::Escape($TIMESTAMP)
(Get-Content -Raw $SCHLOGFILE) -replace ('(?ms)\A.*?\r?\n.*?' + $escapedTimeStamp + '.*?\r?\n') `
-replace ('(?m)^.*?' + $escapedTimeStamp + '.*\r?\n') |
Set-Content -NoNewline $PARSEFILE
Обратите внимание, что [regex]::Escape()
используется, чтобы убедиться, что значение $TIMESTAMP
обрабатывается как литерал , даже если оно содержит метасимволы регулярных выражений (chars. С особым значением для механизма регулярных выражений). ).
Ваш ksh
код этого не делает (и это нетривиально в ksh
), поэтому, если - наоборот - $TIMESTAMP
следует интерпретировать как как регулярное выражение, просто пропустите этот шаг и используйте $TIMESTAMP
напрямую.
Оператор -replace
основан на регулярных выражениях и использует механизм регулярных выражений .NET.
Для использования Get-Content
-Raw
требуется PSv3 +, а для Set-Content
-NoNewline
требуется PSv5 +. Вы можете заставить эту команду работать в более ранних версиях, но это требует больше усилий.
Вызов вышеприведенного из cmd.exe
(командный файл) становится довольно громоздким - и вам всегда следует опасаться цитирования - но это должно работать:
@powershell.exe -noprofile -command "$escapedTimeStamp = [regex]::Escape('%TIMESTAMP%'); (Get-Content -Raw '%SCHLOGFILE%') -replace ('(?ms)\A.*?\r?\n.*?' + $escapedTimeStamp + '.*?\r?\n') -replace ('(?m)^.*?' + $escapedTimeStamp + '.*\r?\n') | Set-Content -NoNewline '%PARSEFILE%'"
Обратите внимание, как аргумент -command
передается в виде одной строки "..."
, что в конечном итоге является наиболее безопасным и концептуально чистым способом передачи кода в PowerShell.
Также обратите внимание на необходимость встраивания пакетных переменных как %varname%
в команду, и, поскольку они заключены во вложенный '...'
выше, предполагается, что их значения не содержат '
символов.
Поэтому рассмотрите возможность реализации всего своего сценария в Powershell - в вашем распоряжении будет гораздо более мощный язык сценариев, и вы избежите головной боли при цитировании, которая исходит от соединяя два разнородных мира.