Powershell替换存储在许多文件夹中的多个文件中的文本

时间:2022-07-25 02:57:20

I want to replace a text in multiple files and folders. The folder name changes, but the filename is always config.xml.

我想替换多个文件和文件夹中的文本。文件夹名称更改,但文件名始终为config.xml。

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

When I run the above script it works, but it writes the whole text in config.xml about 20 times. What's wrong?

当我运行上面的脚本时,它可以正常运行,但它会将整个文本写入config.xml大约20次。怎么了?

3 个解决方案

#1


14  

$filename is a collection of System.IO.FileInfo objects. You have to loop to get the content for each file : this should do what you want :

$ filename是System.IO.FileInfo对象的集合。你必须循环来获取每个文件的内容:这应该做你想要的:

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

#2


6  

$filename is an array of filenames, and it's trying to do them all at once. Try doing them one at a time:

$ 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
}

#3


3  

In general, you should use the pipeline and combine the ForEach-Object and/or Where-Object CmdLets.

通常,您应该使用管道并组合ForEach-Object和/或Where-Object CmdLets。

In your case, this would like like something more akin to:

在你的情况下,这就像是类似于:

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

Which can be shortened somewhat to:

哪个可以缩短到:

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

#1


14  

$filename is a collection of System.IO.FileInfo objects. You have to loop to get the content for each file : this should do what you want :

$ filename是System.IO.FileInfo对象的集合。你必须循环来获取每个文件的内容:这应该做你想要的:

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

#2


6  

$filename is an array of filenames, and it's trying to do them all at once. Try doing them one at a time:

$ 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
}

#3


3  

In general, you should use the pipeline and combine the ForEach-Object and/or Where-Object CmdLets.

通常,您应该使用管道并组合ForEach-Object和/或Where-Object CmdLets。

In your case, this would like like something more akin to:

在你的情况下,这就像是类似于:

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

Which can be shortened somewhat to:

哪个可以缩短到:

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