使用 Powershell 重命名文件和文件中的内容

Renaming of files and content within files using Powershell

提问人:jennab 提问时间:9/11/2023 更新时间:9/12/2023 访问量:53

问:

有人可以支持使用Powershell重命名文件和文件中的内容吗:

  • 根文件夹包含文件(xml、txt 等),也包含本身包含文件的子文件夹
  • 应重命名所有子文件夹中所有包含的文件中出现的所有特定措辞
  • 其他要求:
    • 示例中的“abc”也可以是大写字母,甚至可以是混合字母(例如“ABC”、“Abc”)
    • 此外,文件名应重命名。这有效: .还需要添加什么才能涵盖大写字母和/或混合字母?以及如何将其包含在下面的脚本中,以一次性重命名所有子文件夹中的所有文件?ls | Rename-Item -NewName {$_ -replace 'uvw', 'xyz' }

尝试根据此处有关该主题的其他帖子包含其他参数,但偶然发现了访问被拒绝的问题和其他问题。它仅在提供用于使用以下脚本的单个子文件夹时才有效 - 不包括提到的额外要求。请建议使其符合上述要求:$filePath

$filePath = "C:\root_folder"
Get-ChildItem $filePath -Recurse | ForEach {
     (Get-Content $_ | ForEach  { $_ -creplace 'abc_123', 'def_123' }) |
     Set-Content $_
}
PowerShell 文件- 批重命名

评论

0赞 Re1ter 9/11/2023
尝试使用正则表达式:脚本将忽略大小写。$_ -replace '[Uu][Vv][Ww]', 'xyz'
1赞 mklement0 9/11/2023
@Re1ter,默认情况下,支持字符串操作的 PowerShell 运算符不区分大小写,包括 ,因此无需执行不区分大小写的匹配(相反,如果需要区分大小写,请使用变体)。如果您想将区分大小写作为正则表达式的一部分,您可以使用内联选项;将它放在开头以覆盖整个正则表达式,或者 - 要使正则表达式的某些部分区分大小写 - 根据需要放置它,然后用 将其重新关闭。简而言之:是更简单的等价物-replace-creplace(?i)(?-i)$_ -replace 'uvw', 'xyz'$_ -creplace '(?i)uvw', 'xyz'

答:

1赞 mklement0 9/11/2023 #1
  • 默认情况下,支持字符串操作的 PowerShell 运算符不区分大小写,包括 -replace,因此无需额外执行不区分大小写的匹配:例如,is 。'uVw' -match 'uvw'$true

    • 仅当明确需要区分大小写时,才使用变体(前缀也可以应用于其他运算符,如 () 和 (),表示区分大小写)。-creplacec-match-cmatch-eq-ceq
  • 如果只想在递归 Get-ChildItem 调用中处理文件,请添加 -File 开关

    • 默认情况下,目录包含在枚举中,尝试对目录进行 Get-Content 调用会导致 Windows PowerShell 中出现“拒绝访问”错误(此后,该错误消息已在 PowerShell (Core) 7+ 中得到改进)。

因此,您可能正在寻找如下内容:

  • 注意事项

    • 在尝试中,您处理目录树中的所有文件;虽然尝试将文件重命名为其现有名称是一种良性的禁操作(如果找不到要替换的字符串),但基于操作无条件重写文件内容会损坏文本文件,并且使用文本文件可以更改其字符编码-replace

    • 因此,最好:

      • 通过添加(例如,添加到调用中)将处理限制为感兴趣的文件类型,如其扩展名所示,如下所示。-Include *.txt, *.xmlGet-ChildItem
      • 使用显式参数来控制输出字符编码。-Encoding
      • 此外,您可能只想在执行实际字符串替换时重写文件。
    • 当操作不区分大小写匹配时,替换字符串按原样使用;例如: 结果为 。-replace'-ABC-' -replace 'abc', 'def''-def-'

      • 您的后续问题是关于根据匹配的文本对替换文本进行大小写匹配,以便上述示例中的结果是'-DEF-'
$filePath = "C:\root_folder"
$include = '*.txt', '*.xml' # adapt as needed
Get-ChildItem -File $filePath -Recurse -Include $include | 
  Rename-Item -WhatIf -PassThru -NewName { $_.Name -replace 'uvw', 'xyz' } |
  ForEach-Object {
     # NOTE: You may have to use an -Encoding argument here to ensure
     #       the desired character encoding.
     ($_ | Get-Content -Raw) -replace 'abc_123', 'def_123' |
       Set-Content -NoNewLine -LiteralPath $_.FullName
  }

注意:上述命令中的 -WhatIf 通用参数预览操作。删除 -WhatIf 并在确定操作将执行所需操作后重新执行。

评论

0赞 mklement0 9/12/2023
感谢您发现错别字,@jennab - 已修复。至于使替换字符串的情况与匹配的情况相同:我不认为有任何内置内容,但这是一个有趣的问题,我鼓励您创建一个专门针对此的新问题。(一旦你这样做了,请随时在这里联系我)。Rename-Object