Замените несколько строк в нескольких файлах одним и тем же шаблоном в Powershell - PullRequest
0 голосов
/ 09 марта 2020

Я пытался заменить шаблон линий из нескольких. xml файлов, используя скрипты Powershell

По какой-то причине я все еще не мог понять, как это сделать даже для одного файла это то, что я использовал

$loc = file
$file = Get-Content $loc -Raw
$file -replace "(\<!-- First.*?\/>)","blank"

И эти строки, которые я хочу заменить

<!-- First -->
<prop classproperty="1"
     packageproperty="1.2"
/>

В основном я пытался использовать свойство -Raw для Powershell считал в одну строку и попытался заменить, используя выражение регулярного выражения (\<!-- Weather.*?\/>). Я хочу заменить из комментария на закрытие тега prop. Но каждый раз, когда я запускаю свой скрипт, он ничего не меняет. Что я делаю неправильно? Я запустил этот код регулярного выражения с файлом в одной строке, используя https://regexr.com/, и он отлично работает

Кроме того, как я могу применить одно и то же изменение для нескольких файлов? Я пытался это сделать, но он возвращает ошибку, сообщающую, что у меня нет разрешения на путь

$loc = Get-Location
Get-ChildItem -Path $loc\*.* -Filter '*_property.xml' -Recurse | ForEach-Object {
    (Get-Content -path $loc -Raw) -replace '(\<!-- Weather.*?\/>)','white'
}

Спасибо!

Ответы [ 2 ]

1 голос
/ 10 марта 2020

Хотя этот ответ от thepip3r предоставляет решение для вашего регулярного выражения, я бы не рекомендовал работать с xml таким образом - смотрите, как RegEx соответствует открытым тегам, кроме X HTML автономные теги .


Лучшим способом было бы использовать [xml] тип:

$fileContents = @"
<!-- First -->
<prop classproperty="1"
    packageproperty="1.2"
/>
"@

$xml = [xml]$fileContents

# specify the comment you want to replace in the where statement
$xml.ChildNodes | where {($_.Name -match '#comment' -and $_.value -match 'First')} | ForEach-Object {
    # you can add a new comment
    $child = $xml.CreateComment(" New Comment ")
    [void]$_.ParentNode.AppendChild($child)

    # or you could just remove
    [void]$_.ParentNode.RemoveChild($_)
}

# specify what else you want to remove in the where statement
$xml.ChildNodes | where {$_.name -eq 'prop' -and $_.classproperty -eq '1'} | ForEach-Object {
    [void]$_.ParentNode.RemoveChild($_)
}

$xml.Save('C:\temp\newxml.xml')

Изменить Get-Content -path $loc на Get-Content $_.Fullname в вашем ForEach-Object (чтобы указать текущий файл. В противном случае вы пытаетесь получить содержимое каталога $loc)

1 голос
/ 10 марта 2020

Вам необходимо добавить (? Мс) в начало вашего RegEx:

$file -replace "(?ms)(\<!-- First.*?\/>)","blank"

Это говорит механизму RegEx о том, что ваши символы подстановки должны занимать несколько строк.

Причина он работал на сайте, который вы упомянули, а не когда вы копировали его непосредственно в сценарий, потому что есть несколько различных механизмов RegEx, которые интерпретируют синтаксис RegEx. Вы заметите, что на веб-сайте, на который вы ссылаетесь, перечислены два разных движка в верхнем правом углу страницы с Javascript по умолчанию и PCRE в раскрывающемся списке.

. NET заявляет о поддержке механизма регулярных выражений PERL 5:

In. NET, шаблоны регулярных выражений определяются специальным синтаксисом или языком, который совместим с Perl 5 регулярными выражениями и добавляет некоторые дополнительные функции, такие как сопоставление справа налево.

https://docs.microsoft.com/en-us/dotnet/standard/base-types/regular-expressions

.. но это немного вводит в заблуждение, поскольку PERL обеспечивает поддержку PCRE в версии 5.10:

Начиная с Perl 5.10.0, Perl поддерживает несколько специфичных для Python / PCRE расширений синтаксиса регулярных выражений. В то время как Perl программистам рекомендуется использовать синтаксис Perl -specifi c, также допускается следующее

https://perldoc.perl.org/perlre.html#PCRE% 2f Python -Поддержка

поэтому я предполагаю, что NET реализовал выражения в стиле Perl до поддержки PCRE, и, следовательно, используемый вами веб-сайт может не точно отражать, когда определенное регулярное выражение будет успешно проверено в сайт, который вы разместили, вообще. По крайней мере, у него есть высокая вероятность того, что он будет последовательно несовместим с его результатами в PowerShell.

Проблема с вашим l oop и несколькими файлами, очевидно, является разрешениями (о чем свидетельствует исключение). Получите права на расположение файла и, если они у вас есть, запустите ваш сценарий с повышенными правами (щелкните правой кнопкой мыши -> Запуск от имени администратора)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...