Замените неуникальную строку текста под уникальной строкой текста в текстовом файле, используя powershell - PullRequest
0 голосов
/ 24 сентября 2019

У меня есть следующий текстовый файл.

[AppRemover]
Enable=0

[CleanWipe]
Enable=0

[RerunSetup]
Enable=0

Как изменить Enable=0 на Enable=1 только для [CleanWipe]?

Ниже описано, как я планирую использоватькод с моим файлом.

$Path = C:\temp\file.txt
$File = Get-Content -Path $Path
# Code to update file
$File | Out-File $Path

1 Ответ

1 голос
/ 24 сентября 2019

Вы можете использовать -replace для обновления значения, если оно равно 0.

$Path = C:\temp\file.txt
(Get-Content $Path -Raw) -replace "(?<text>\[CleanWipe\]\r?\nEnable=)0",'${text}1' |
    Set-Content $Path

Использование модуля, анализирующего INI-файлы, будет лучшим решением.Я бы порекомендовал попробовать PsIni .

Объяснение:

Переключатель -Raw считывает содержимое файла в виде одной строки.Это облегчает работу с символами новой строки.

-replace выполняет сопоставление с регулярным выражением, а затем заменяет его.Ниже приведена разбивка на соответствие регулярному выражению.

  • (?<text>) - именованная группа захвата.Все, что соответствует этой группе захвата, может быть вызвано в строке замены как '${text}'.
  • \[CleanWipe\] - буквальное совпадение [CleanWipe] при экранировании символов [] с \.
  • \r? - необязательный возврат каретки
  • \n - символ новой строки
  • Enable= - буквальное совпадение
  • 0 - буквальное совпадение

Строка замены - это содержимое группы захвата и 1, если совпадение существует.Технически, группа захвата не нужна, если вы хотите использовать вместо нее позитивный взгляд.Позитивный взгляд за утверждением (?<=).Это решение будет выглядеть следующим образом:

$Path = C:\temp\file.txt
(Get-Content $Path -Raw) -replace "(?<=\[CleanWipe\]\r?\nEnable=)0",'1' |
    Set-Content $Path

Проблема с -replace решениями в том виде, в котором они написаны, заключается в том, что они будут обновлять файл независимо от того, какие изменения вносятся в содержимое.Вам нужно будет добавить дополнительное сравнение, чтобы предотвратить это.Другими проблемами могут быть лишние пробелы в любой из этих строк.Вы можете учесть это, добавив \s*, где, по вашему мнению, эти возможности могут существовать.


Альтернатива с дополнительными шагами:

$file = Get-Content $Path
$TargetIndex = $file.IndexOf('[CleanWipe]') + 1
if ($file[$TargetIndex] -match 'Enable=0') {
    $file[$TargetIndex] = 'Enable=1'
    $file | Set-Content $Path
}

Это решение поможетобновляйте файл только в том случае, если он соответствует условию соответствия.Он использует метод массива IndexOf(), чтобы определить, где находится [CleanWipe].Затем предполагается, что строка, которую вы хотите изменить, находится в следующем индексе.

IndexOf() - не единственный способ найти индекс.Метод требует, чтобы ваша строка точно соответствовала строке.Вы можете использовать Select-String (без учета регистра по умолчанию), чтобы вернуть номер строки.Поскольку это будет номер строки, а не индекс (индексы начинаются с 0, а номера строк начинаются с 1), это всегда будет нужный номер индекса.

$file = Get-Content $Path
$TargetIndex = ($file | Select-String -Pattern '[CleanWipe]' -SimpleMatch).LineNumber
if ($file[$TargetIndex] -match 'Enable=0') {
    $file[$TargetIndex] = 'Enable=1'
    $file | Set-Content $Path
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...