使用 powershell 动态查找和替换子文件夹中多个特定文件的文本

Find & Replace text from multiple specific files from sub folders dynamically using powershell

我正在开发 Azure CD 管道,我想更改存在于以下文件夹结构中的多个文件的内容。

MainFolder => SubFolder1 => myFile1.txt
              SubFolder2 => myFile2.txt
              SubFolder3 => myFile3.txt

我想用powershell实现我上面的需求,我试过下面的代码

$filepath = 'C:\Users\ashishjain06\Desktop\MainFolder'
$mydata = Get-ChildItem $filepath -include *.txt -recurse | Select-Object fullName
$totalRecords = $mydata.Count
for($x = 0; $x -lt $totalRecords; $x++)
{
    ((Get-Content -path $mydata[$x] -Force) -replace 'oldText','newText') | Set-Content -Path $mydata[$x]
}

当我 运行 以上代码时,它会给我以下输出。

Get-Content : Cannot find drive. A drive with the name '@{FullName=C' does not exist.
At line:6 char:7
+     ((Get-Content -path $mydata[$x] -Force) -replace 'oldText ...
+       ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (@{FullName=C:String) [Get-Content], DriveNotFoundException
    + FullyQualifiedErrorId : DriveNotFound,Microsoft.PowerShell.Commands.GetContentCommand

Get-Content : Cannot bind argument to parameter 'Path' because it is null.
At line:6 char:25
+     ((Get-Content -path $mydata[$x] -Force) -replace 'oldText ...
+                         ~~~~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [Get-Content], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.GetContentCommand

Get-Content : Cannot bind argument to parameter 'Path' because it is null.
At line:6 char:25
+     ((Get-Content -path $mydata[$x] -Force) -replace 'oldText ...
+                         ~~~~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [Get-Content], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.GetContentCommand

Get-Content : Cannot bind argument to parameter 'Path' because it is null.
At line:6 char:25
+     ((Get-Content -path $mydata[$x] -Force) -replace 'oldText ...
+                         ~~~~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [Get-Content], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.GetContentCommand

Get-Content : Cannot bind argument to parameter 'Path' because it is null.
At line:6 char:25
+     ((Get-Content -path $mydata[$x] -Force) -replace 'oldText ...
+                         ~~~~~~~~~~~
    + CategoryInfo          : InvalidData: (:) [Get-Content], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.GetContentCommand

我是powershell新手,请帮我解决这个问题。

它仍然是一个带有 属性 的对象,除非你这样做:

select-object -expandproperty fullname

Get-ChildIItem returns(一个数组)FileInfoObjects 具有一堆属性,
Select-Object 删除除所选对象之外的所有对象,但它仍然是一个对象,其中包含一个 属性 FullName.
参见 $mydata | Get-Member

一种方法是Select-Object -ExpandProperty FullName,
另一个是以下脚本中使用的 property dereference operator .

要让脚本在任何用户上运行,请不要包含固定路径,使用 $Env:USERPROFILE 或更好的方法,让系统评估当前用户的桌面文件夹(可能会重新定位)。

让 powershell 使用 foreach:

而不是按索引迭代数组 $mydata
$filepath = Join-Path ([environment]::GetFolderPath('Desktop')) 'MainFolder'
$files = (Get-ChildItem $filepath -Filter *.txt -Recurse).FullName

foreach($file in $files){
   (Get-Content -path $file -Force) -replace 'oldText','newText' | Set-Content -Path $file
}

Select-Object替换为ForEach-Object,即:

$filepath = 'C:\Users\ashishjain06\Desktop\MainFolder'
#$mydata = Get-ChildItem $filepath -include *.txt -recurse | Select-Object fullName
$mydata = Get-ChildItem $filepath -include *.txt -recurse | ForEach-Object fullName
$totalRecords = $mydata.Count
for($x = 0; $x -lt $totalRecords; $x++)
{
    ((Get-Content -path $mydata[$x] -Force) -replace 'oldText','newText') | Set-Content -Path $mydata[$x]
}