Метод замены не работает с моими строковыми переменными

Я написал скрипт для извлечения URL-адреса и номера версии из команды svn info репозитория svn и сохранения результата в файле .txt.

$revision и $url являются строками, поэтому метод replace должен работать с ними, но это не так. Возможно, что-то не так в моем коде, вызывающем это?

$TheFilePath = "C:\Users\MyPC\REPOSITORY\NewProject\OUTPUT.txt"

echo "#- Automatic Package Update `n----------"| Out-File -FilePath $TheFilePath
 
$url = svn info C:\Users\MyPC\REPOSITORY\NewProject\trunk | Select-String -Pattern 'URL' -CaseSensitive -SimpleMatch | select-object -First 1 
$url | Add-Content -path $TheFilePath
$revision = svn info C:\Users\MyPC\REPOSITORY\NewProject\trunk | Select-String -Pattern 'Revision' -CaseSensitive -SimpleMatch | $revision.Replace('Revision','srcrev')
$revision | Add-Content -path $TheFilePath 

вот вывод svn info (нерелевантные выводы были опущены):

Path: .
Working Copy Root Path: C:\Users\MyPC\REPOSITORY\NewProject\trunk
URL: https://svn.mycompany.de/svn/NewProject/trunk
Relative URL: ^/trunk
Repository Root: https://svn.mycompany.de/svn/NewProject
Revision: 5884

И вот что я получаю внутри .txt файла, запуская код:

#- Automatic Package Update 
----------
URL: https://svn.mycompany.de/svn/NewProject/trunk
Revision: 5884
----------

🤔 А знаете ли вы, что...
С PowerShell можно создавать расписания задач и автоматически выполнять скрипты в определенное время.


1
54
2

Ответы:

$revision не существует до тех пор, пока не будет выполнена команда svn.

Используйте командлет ForEach-Object и обратитесь к текущему совпадению как $_, чтобы изменить встроенный объект вывода — совпавшая строка в выводе из Select-String хранится в свойстве с именем Line:

$revision = svn info C:\Users\MyPC\REPOSITORY\NewProject\trunk |Select-String -Pattern 'Revision' -CaseSensitive -SimpleMatch |ForEach-Object { $_.Line.Replace('Revision', 'srcrev') }

Решено

Глядя на пример вывода svn info здесь и пример, который вы только что предоставили, вы должны быть в состоянии получить необходимую информацию проще с ConvertFrom-StringData, чем с Select-String.

В PowerShell < 7.x вы можете использовать ConvertFrom-StringData на выходе svn info после изменения разделителя двоеточия (:) на знак равенства (=), чтобы получить хеш-таблицу со всеми свойствами и значениями. Затем, используя рассчитанные свойства, вы можете извлечь интересующие вас элементы и сохранить их в виде файла CSV, например, следующим образом:

$svnInfo = svn info 'C:\Users\MyPC\REPOSITORY\NewProject\trunk'
$result  = $svnInfo -replace '(?<!:.*):', '=' | ConvertFrom-StringData | 
           Select-Object @{Name = 'URL'; Expression = {$_['URL']}}, 
                         @{Name = 'srcrev'; Expression = {$_['Revision']}}

# output on screen
$result | Format-Table -AutoSize

# output to CSV file
$result | Export-Csv -Path 'C:\Users\MyPC\REPOSITORIES\NewProject\OUTPUT.csv' -NoTypeInformation

Детали регулярного выражения для -replace, чтобы заменить только первое появление двоеточия:

(?<!        Assert that it is impossible to match the regex below with the match ending at this position (negative lookbehind)
   :        Match the character “:” literally
   .        Match any single character
      *     Between zero and unlimited times, as many times as possible, giving back as needed (greedy)
)          
:           Match the character “:” literally

Если вы используете PowerShell 7 или выше, tghings становится проще, потому что у вас есть дополнительный параметр -Delimiter:

$svnInfo = svn info 'C:\Users\MyPC\REPOSITORY\NewProject\trunk'
$result  = $svnInfo -replace '(?<!:.*):', '=' | ConvertFrom-StringData -Delimiter ':' | 
           Select-Object @{Name = 'URL'; Expression = {$_['URL']}}, 
                         @{Name = 'srcrev'; Expression = {$_['Revision']}}
# output on screen
$result | Format-Table -AutoSize

# output to CSV file
$result | Export-Csv -Path 'C:\Users\MyPC\REPOSITORIES\NewProject\OUTPUT.csv' -NoTypeInformation