Строка замены содержимого набора Powershell - PullRequest
0 голосов
/ 21 июня 2020

Итак, мне нужно сохранить строку, которая была заменена в файлах.

Я делаю что-то не так, но не могу понять, что!

Мой код:

    Get-ChildItem -Path C:\Users\user\Documents -Recurse -Include "*.txt" -File |  Select-String  -Pattern \b192\.168\.10\.2\b , \b192\.168\.10\.11\b -AllMatches -List |  Foreach-Object { $_ -replace '\b192\.168\.10\.2\b', "DEV" -and $_ -replace '\b192\.168\.10\.11\b', "QUAL" | Set-Content $_}

И дает мне следующую ошибку:

   Set-Content : Could not open the alternate data stream '1:192.168.10.11' of the file 'C:\Users\user\Documents\result.txt'.
   At line:1 char:323
   + ... place '\b192\.168\.10\.11\b', "QUAL" | Set-Content $_}
   +                                                         
   + CategoryInfo : ObjectNotFound: (C:\Users\paulo....ents\result.txt:String) [Set-Content], FileNotFoundException
   + FullyQualifiedErrorId :  GetContentWriterFileNotFoundError,Microsoft.PowerShell.Commands.SetContentCommand

   Set-Content : Could not open the alternate data stream '1:192.168.10.11' of the file 
  'C:\Users\user\Documents\test.txt'
   At line:1 char:323 ... place '\b192\.168\.10\.11\b', "QUAL" | Set-Content $_}                                                             
   CategoryInfo : ObjectNotFound: (C:\Users\user\test.txt:String) [Set-Content], FileNotFoundException
   FullyQualifiedErrorId : GetContentWriterFileNotFoundError,Microsoft.PowerShell.Commands.SetContentCommand

Спасибо за любую помощь!

Ответы [ 2 ]

2 голосов
/ 21 июня 2020

Оператор -and используется внутри тестов if, например if(this -and that). Вы должны изменить действия двойной замены с

$_ -replace '\b192\.168\.10\.2\b', "DEV" -and $_ -replace '\b192\.168\.10\.11\b', "QUAL"

на

$_ -replace '\b192\.168\.10\.2\b', "DEV" -replace '\b192\.168\.10\.11\b', "QUAL"

Кроме того, если я правильно понимаю вопрос, вы хотите найти все замены строк в файле и получить все, вам нужно удалить переключатель -List из Select-String.

Далее, как Матиас объясняет в его ответ , вам нужно использовать свойство Path из текущего совпадения чтобы получить файл FullName. Однако, если вы сразу передадите это в Set-Content, вы получите исключение, потому что файл уже используется, и вы не можете писать в тот же файл.

Ниже создается новый файл по тому же пути , с добавлением _replacements к имени файла

# use '-Include' instead of '-Filter' if you need more file extensions to filter on
Get-ChildItem -Path 'C:\Users\user\Documents' -Recurse -Filter "*.txt" -File |  
Select-String  -Pattern '\b192\.168\.10\.2\b', '\b192\.168\.10\.11\b' -AllMatches |  
Foreach-Object { 
    $file = '{0}_replacements{1}' -f [System.IO.Path]::GetFileNameWithoutExtension($_.Path),
                                     [System.IO.Path]::GetExtension($_.Path)
    $target = Join-Path -Path ([System.IO.Path]::GetDirectoryName($_.Path)) -ChildPath $file
    $_ -replace '\b192\.168\.10\.2\b', "DEV" -replace '\b192\.168\.10\.11\b', "QUAL"  | 
    Add-Content -Path $target 
}

В результате получается файл с именем 'C: \ Users \ user \ Documents \ test_replacements.txt'

C:\Users\user\Documents\test.txt:4:DEV
C:\Users\user\Documents\test.txt:7:QUAL

исходный файл 'C: \ Users \ user \ Documents \ test.txt' не будет изменен.

2 голосов
/ 21 июня 2020

Внутри блока ForEach-Object $_ будет ссылаться на текущий результат совпадения, возвращенный Select-String - чтобы получить путь к файлу, обратитесь к свойству Path:

... | ForEach-Object { ... |Set-Content -LiteralPath $_.Path}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...