5

我正在尝试写一个等价的

find -name "*.xml" | xargs grep -l "Search String" 
       | xargs perl -p -i -e 's/Search String/Replace String/g'

在PowerShell中。这就是我想出的。

Get-ChildItem 'D:\code\cpp\FileHandlingCpp\input - Copy' -Recurse |
Select-String -SimpleMatch $src_str | 
foreach{(Get-Content $_.path) | ForEach-Object { $_ -replace $src_str, $target_str }}

我收到错误“该进程无法访问该文件,因为它正被另一个进程使用”。所以我想出了如下所示的多行版本。我现在可以替换字符串,除了$src_str. $src_str 有什么问题?

$src_str="<?xml version=""1.0"" encoding=""UTF-8"" standalone=""yes"" ?>"
$target_str=""
echo $src_str

foreach ($var in (Get-ChildItem 'D:\code\cpp\FileHandlingCpp\input - Copy' -Recurse 
                     | Select-String -SimpleMatch $src_str).Path) 
{    
  (Get-Content $var) | ForEach-Object { $_ -replace $src_str, $target_str }
    | Set-Content $var    
}
4

2 回答 2

9

也许这将有助于回到实现与 Unix 版本等效的最初目标。这里基本上是等效的 PowerShell 版本。

$search = '<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>'
$replace = 'test'
$dir = 'D:\code\cpp\FileHandlingCpp\input - Copy'

dir -Path $dir -Recurse -Filter *.xml | ForEach-Object {
    (Get-Content -Path $_.FullName) -replace $search, $replace | 
        Set-Content $_.FullName
}

注意 - 注意可能因重写文件而发生的文本文件编码更改。如果需要使用Set-Content's-Encoding参数,可以指定输出编码,例如ASCII.

于 2013-05-29T01:59:46.480 回答
4

这花了我一段时间才弄清楚,但我明白了!

这是一个单行。只需转到您要开始的文件夹并输入。更改 file.name (如果需要,使用通配符)和 string1 和 string2 与您要搜索的文件名和您要替换为 string2 的 string1 .

因此,这会递归搜索文件夹,并且对于每个文件,它都会用另一个字符串替换一个字符串并保存它。基本上是Get-Childitem | ForEach-Object 替换和保存。

可以了,好了!

get-childitem -include file.name -Recurse | ForEach-Object { ( Get-Content -Path $_.FullName ) -replace 'string1', 'string2' | set-content $_.fullname }
于 2013-08-13T20:58:00.913 回答