【问题标题】:Loop through folders/files and replace word循环浏览文件夹/文件并替换单词
【发布时间】:2019-12-23 13:52:23
【问题描述】:

尝试遍历包含多个 html 文件的文件夹/子文件夹以查找特定字符串/单词。

一旦 powershell 脚本找到它 - 它将列出哪些文件包含匹配的单词。 可能会提示用户替换单词或设置变量,例如 $replaceword = 'test2'

$match = "THIS IS A TEST"
#$replacement = Read-Host "Please enter a solution name"
$files = Get-ChildItem -path C:\Users\testfolder -filter *THIS IS A TEST* -Recurse
$files
    Sort-Object -Descending -Property { $_.FullName }
    #Rename-Item -newname { $_.name -replace $match, $replacement } -force
$files = Get-ChildItem -path C:\Users\testfolder -include *.html -Recurse
foreach($file in $files)
{
    ((Get-Content $file.fullname) -creplace $match)
read-host -prompt "Done! Press any key to close."
}

【问题讨论】:

  • 您要替换匹配的文件名或文件内容吗?
  • 这些 html 文件中的单词/字符串.. 不是文件名

标签: powershell


【解决方案1】:

您可以执行以下操作,这将替换C:\Users\testfolder 目录结构中.html 文件的匹配内容

$matchString = 'THIS IS A TEST'
$replaceString = 'New String'
$files = Get-ChildItem -Path 'C:\Users\testfolder' -filter *.html -Recurse
foreach ($file in $files) {
    $matchFound = $false
    $output = switch -regex -file $file.fullname {
        $matchString { $_ -replace $matchString,$replaceString
                       $matchFound = $true
        }
        default { $_ }
    }
    if ($matchFound) {
        $output | Set-Content $file.fullname
    }
}

如果您确实想要一个交互式提示来替换字符串,您可以将$replaceString 移动到脚本逻辑中的其他位置并添加Read-Host 命令。

说明:

脚本的顶部包含$matchString(您要匹配的区分大小写的字符串)和$replaceString(替换字符串)。

Get-ChildItem 使用-Filter 查找所有以 HTML 扩展名结尾的文件。 -Recurse 开关用于从路径中搜索所有子目录。

switch 语句用于支持Get-Content,因为它通常执行得更快。我们只想在找到匹配项时覆盖文件。 $matchFound$false 开头,找到匹配项后将变为 $true

-creplace 在这里使用,因为您的源代码使用了它。 -creplace 执行区分大小写的正则表达式匹配和替换。


交互式替代方案:

对于交互式元素,您可以要求用户在每次找到匹配项时输入替换字符串。这只是将$replaceString 赋值移动到switch 语句中,并列出包含匹配项的文件。

$matchString = 'THIS IS A TEST'
$files = Get-ChildItem -Path 'C:\Users\testfolder' -filter *.html -Recurse
foreach ($file in $files) {
    $matchFound = $false
    $output = switch -regex -file $file.fullname {
        $matchString { $replaceString = Read-Host -Prompt "$($file.fullname) contains '$matchString'. Enter your replacement string"
                       $_ -replace $matchString,$replaceString
                       $matchFound = $true
        }
        default { $_ }
    }
    if ($matchFound) {
        $output | Set-Content $file.fullname
    }
}

【讨论】:

  • 我尝试运行上面的脚本 - 但没有成功。它甚至不检查文件夹
  • 它适用于 PowerShell v5。它为所有 *.html 文件递归 c:\users\testfolder。
  • 你能解释一下你说它不检查文件夹是什么意思吗?如果c:\users\testfolder 不是您的起点,则需要使用正确的路径更新代码。
  • 这是我的起点,但在 c:users\testfolder 里面有 html 文件和包含 html 文件的子文件夹
  • 管理员 - 它的工作原理,感谢您的帮助。现在对于 matchString - 我怎样才能避免区分大小写 - ? $matchstring = "TEST" won't find = 'test' 作为例子
【解决方案2】:

这样的东西怎么样,这是一个更简单的例子:

$files = Get-ChildItem -Path c:\path\here -Recurse 
$matchString = 'THIS IS A TEST'
$replacementString = 'replace'

foreach ($i in $files){
    #Check its a file
    if (!$i.PSIsContainer){
        #Check the name contains the $matchString
        if ($i.Name -match $matchString){

            Set-Content -Path $i.FullName -Value $replacementString -Confirm:$true
        }
    }
}

如果我误解了你想要什么,请告诉我:)

【讨论】:

  • 它甚至没有检查文件夹 - 我有一个包含多个包含 html 文件的子文件夹的目录。
  • 什么意思? Get-ChildItem 命令中的路径你改了吗?
  • 是的,我确实改变了路径
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-12-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-07
  • 1970-01-01
相关资源
最近更新 更多