Выборочное обновление строк в файле на основе их содержимого - PullRequest
0 голосов
/ 27 февраля 2019

Я новичок в сценариях Powershell и прошел учебное пособие PowerShell, чтобы выполнить свои текущие требования к сценариям.

Я пытаюсь добавить восклицательный знак в строку путем сопоставления с шаблоном.У меня есть файл test.default, подобный приведенному ниже:

"/AgentSetup/__type__"

"/AgentSetup/__name__"

"/AgentSetup/preloadedKs"

"/AgentSetup/preloadedKMsArch"

"/AgentSetup/loadOnlyPreloadedKMs"

Больше таких строк в файле

Итак, я пытаюсь добавить восклицательный знак в начало строки, сопоставив, например,если я ищу "/ AgentSetup / preloadedKs" = {REPLACE = ""}, то в файле это должно выглядеть так:

"/AgentSetup/__type__"

"/AgentSetup/__name__"

"/AgentSetup/preloadedKs"

!"/AgentSetup/defaultAccount"

"/AgentSetup/preloadedKMsArch"

"/AgentSetup/loadOnlyPreloadedKMs"

Я пытался выполнить следующие команды, чтобы добиться этого, но безуспешно

$TEST = "C:\Asset\config.default"
$Pattern = "/AgentSetup/defaultAccount"
$var = "!" + (Select-String -Path $TEST -pattern $Pattern | Out-String)
$var
$var + (Get-Content $TEST -Raw) | Set-Content $TEST

Вышеприведенные команды не просто добавляют восклицательный знак, но и добавляют повторяющуюся запись в файл следующим образом:

!

test.default:103:"/AgentSetup/defaultAccount"

Я прошел учебные пособия powershell Add-Content и Select-String, даже когда искал Get-Content.Пожалуйста, направьте меня в правильном направлении, чтобы я мог достичь этого, это было бы полезно.

1 Ответ

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

С вашим подходом есть две проблемы:

  • Как Матиас Р. Джессен предлагает в комментарии, вместо того, чтобы передать Select-String вывод вызова на Out-String [1] , доступ к свойству .Line результата, содержащего только совпадающую строку.

    • Select-String не выводит строки , выводит информацию о совпадении объекты , чье .Line свойство содержит соответствующиестрока (строка).

    • Обратите внимание, что есть предложение с подсвеченным зеленым светом, которое еще не реализовано в Windows PowerShell Core 6.2.0, чтобы разрешить Select-String напрямую генерировать строки, используяпредлагаемый переключатель -Raw - см. https://github.com/PowerShell/PowerShell/issues/7713

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

Я предлагаю использовать другой файлв целом, основываясь на операторе -replace, что делает решение более кратким и быстрым:

(Get-Content $TEST) -replace '^"/AgentSetup/preloadedKs"$', '!$&' | Set-Content $TEST
  • ^ соответствует началу каждой входной строки и$ конец, так что сопоставляются только строки, которые не содержат ничего, кроме строки поиска.

  • $& - это заполнитель того, что было сопоставлено, то есть исходная строка в данном случае;Подробнее о -replace и этих заполнителях см. этот ответ .

Обратите внимание, что это обновляет строку в исходном положении.

Заключениевызов Get-Content в (...) гарантирует, что файл будет прочитан полностью, что позволяет записывать обратно в тот же файл с Set-Content в том же конвейере;хотя это удобно, он несет небольшой риск потери данных, если запись в файл прерывается.


[1] Цель Out-String - создать строковые представленияобъекты , как если бы они выводились на консоль , что обычно не подходит для программной обработки;даже использование .ToString() на объектах match-info (или размещение их внутри "...") не будет работать, как предполагалось в этом случае, потому что результирующее представление также включает в себя имя входного файла.

...