使用PowerShell进行搜索和替换

3
我正在使用下面的PowerShell脚本来搜索和替换,它能正常工作。
$files = Get-ChildItem 'E:\replacetest' -Include "*.txt" -Recurse | ? {Test-Path $_.FullName -PathType Leaf}

foreach($file in $files)
{
    $content = Get-Content $file.FullName | Out-String
    $content| Foreach-Object{$_ -replace 'hello' , 'hellonew'`
                                -replace 'hola' , 'hellonew' } | Out-File $file.FullName -Encoding utf8
}

问题在于脚本还修改了那些没有匹配文本的文件。我们如何忽略那些没有匹配文本的文件呢?

有没有忽略几个匹配文本的选项。例如,文件还包括文件路径,如c:/hola/hello.xml。我想包含一个正则表达式或条件,以便在/hola/之间不更改hola,或者如果它是hello.xml这样的文件名,则更改其他出现。 - user2628187
2个回答

3
您可以使用match来查看内容是否实际更改。因为您总是使用out-file进行编写,所以文件将被修改。
$files = Get-ChildItem 'E:\replacetest' -Include "*.txt" -Recurse | Where-Object {Test-Path $_.FullName -PathType Leaf}

foreach( $file in $files ) { 
    $content = Get-Content $file.FullName | Out-String
    if ( $content -match ' hello | hola ' ) {
        $content -replace ' hello ' , ' hellonew ' `
                 -replace ' hola ' , ' hellonew ' | Out-File $file.FullName -Encoding utf8
        Write-Host "Replaced text in file $($file.FullName)"
    }    
}

脚本修改的文件是否可以输出? - user2628187
有没有忽略几个匹配文本的选项。例如,文件还包括文件路径,如c:/hola/hello.xml。我想包含一个正则表达式或条件,以便在/hola/之间不更改hola,或者如果它是hello.xml这样的文件名,则更改其他出现。 - user2628187
当然,我已经在上面添加了它。 - Shawn Esterman
你可以使用-replace正则表达式替换方法。我添加了空格,但它不会替换任何以句号结尾且没有包含在空格中的内容。你应该查阅一些相关文档以获取更具体的替换方法。 - Shawn Esterman
抱歉造成困惑,我实际上的意思不是过滤文件夹和文件名,而是文本文件内部的内容。例如,文本文件内的内容为 hola hello C:/hola/hello.txt,我想将其更改为 hellonew hellonew C:/hola/hello.txt,它应该仅更改文本和文本文件路径中匹配的文本应被忽略。 - user2628187

1

你多了一个 foreach,需要加上一个 if 语句:

$files = Get-ChildItem 'E:\replacetest' -Include "*.txt" -Recurse | ? {Test-Path $_.FullName -PathType Leaf}

foreach($file in $files)
{ 
  $content = Get-Content $file.FullName | Out-String
  if ($content -match 'hello' -or $content -match 'hola') {
    $content -replace 'hello' , 'hellonew'`
            -replace 'hola' , 'hellonew' | Out-File $file.FullName -Encoding utf8    
  }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接