PowerShell для замены текста в нескольких файлах, хранящихся во многих папках

Я хочу, чтобы заменить текст в нескольких файлах и папках. Имя папки изменяется, но имя файла всегда является config.XML.

$fileName = Get-ChildItem "C:configapp*config.xml" -Recurse
(Get-Content $fileName) -replace 'this', 'that' | Set-Content $fileName

когда я запускаю вышеуказанный скрипт, он работает, но он записывает весь текст в config.xml около 20 раз. Что случилось?

3 ответов


$filename представляет собой коллекцию System.IO.FileInfo objects. Вы должны сделать цикл, чтобы получить содержимое для каждого файла : это должно делать то, что вы хотите :

$filename | %{
    (gc $_) -replace "THIS","THAT" |Set-Content $_.fullname
}

$filename является массив имен файлов, и он пытается сделать их все сразу. Попробуйте делать их по одному:

$fileNames = Get-ChildItem "C:\config\app*\config.xml" -Recurse |
 select -expand fullname

foreach ($filename in $filenames) 
{
  (  Get-Content $fileName) -replace 'this', 'that' | Set-Content $fileName
}

В общем, вы должны использовать конвейер и объединить ForEach-Object и/или Where-Object командлетов.

в вашем случае это было бы похоже на что-то более похожее:

Get-ChildItem "C:\config\app*\config.xml" -Recurse | ForEach-Object -Process {
    (Get-Content $_) -Replace 'this', 'that' | Set-Content $_
}

который можно несколько сократить до:

dir "C:\config\app*\config.xml" -recurse |% { (gc $_) -replace 'this', 'that' | (sc $_) }