繁体   English   中英

如何使用 PowerShell 从文件名中删除句点?

[英]How do I remove periods from file names using PowerShell?

我正在尝试在 PowerShell 中编写一个脚本,该脚本在文件夹中搜索包含不必要句点的文件,然后从文件名中批量删除句点。

前任。 Example.File.doc ---> ExampleFile.doc

每当我运行代码时,控制台都会返回以下信息:“Rename-Item:无法将参数绑定到参数‘NewName’,因为它是一个空字符串。”

有谁知道问题是什么?

在此先感谢您的帮助!

$files = get-childitem -path "C:\XXXX\XXXX\XXXX" -Recurse 
foreach($file in $files) {

    if($file.Name -match ".") {
        $newName = $file.Name -ireplace (".", "")
        Rename-Item $file.FullName $newName
        Write-Host "Renamed" $file.Name "to $newName at Location:" $file.FullName
    }
}

关于字符串替换的一件事:当我在没有转义句点的情况下尝试您的示例时,它没有替换任何内容并且没有返回任何内容(空字符串),我相信这回答了您的“无法将参数绑定到参数 'NewName' 因为它是一个空字符串”

这通过逃避时期起作用。 此外,它可以使用或不使用括号。

$string = "the.file.name"

$newstring = $string -ireplace "\.", ""
// output: thefilename
$newstring.length
// output: 11

$othernewstring = $string -ireplace ("\.", "")
// output: thefilename
$othernewstring.length
// output: 11

// What the OP tried
$donothingstring = $string -ireplace (".", "")
// output:
$donothingstring.length
// output: 0

这里有一些关于字符串替换的额外信息,仅供参考https://vexx32.github.io/2019/03/20/PowerShell-Replace-Operator/

这里还有一些其他问题。 您应该通过包含-File开关来过滤Get-ChildItem结果以仅返回文件。

您当前的脚本将替换最后一个 . 在您的文件扩展名之前,这会导致一些问题。 您需要使用$File.BaseName$File.Extension属性来解决这个问题。

.replace()方法替换-ireplace

最后,您需要在 If 语句中使用-like条件。 -match条件用于正则表达式,在此处无法正常工作。

$files = get-childitem -Recurse -File 
foreach($file in $files) {

    if($file.BaseName -like "*.*") {
        $newName = $file.BaseName.Replace(".","") + $file.Extension
        Rename-Item $file.FullName $newName
        Write-Host "Renamed" $file.Name "to $newName at Location:" $file.FullName
    }
}

$file.Name -ireplace (".", "")

总是返回一个空字符串,因为-replace运算符-ireplace只是一个别名[1] )对正则表达式(正则表达式)进行操作,其中元字符. 匹配任何字符[2]

由于-replace总是替换它找到的所有匹配项,因此输入中的所有字符都被替换为空字符串,从而产生一个整体的空字符串,并通过$newName将空字符串传递给Rename-Item的(位置隐含的) -NewName参数导致您看到的错误消息。

为了匹配一个. 正则表达式中的逐字字符,您必须将其转义为\\.

$file.Name -replace '\.', '' # Note: no (...) needed; `, ''` optional

请注意,对于要逐字使用的正则表达式和字符串文字,通常最好使用'...'引用而不是"..."

然而:

  • 这也将删除. 字符。 在文件扩展名中,这是不受欢迎的。

  • 此外,您的命令可以精简和简化,如下面的解决方案所示。


简洁的单管道解决方案

Get-ChildItem -File -Path "C:\XXXX\XXXX\XXXX" -Recurse -Include *.*.* | 
  Rename-Item -NewName { ($_.BaseName -replace '\.') + $_.Extension } -WhatIf

注意:上面命令中的-WhatIf常用参数预览操作。 一旦您确定操作会执行您想要的操作,请删除-WhatIf

  • -File限制匹配文件(不是目录)。

  • -Include *.*.*限制匹配至少包含2 的文件名. 字符。

  • 通过管道将文件直接从Get-ChildItem Rename-ItemRename-Item允许您将-NewName参数指定为延迟绑定脚本块( { ... } ),它可以从相应的名称动态派生新名称输入文件,使用从Get-ChildItem接收的System.IO.FileInfo实例的属性。

  • $_.BaseName -replace '\\.' 删除所有文字. 字符。 (在-replace运算符所操作的正则表达式(正则表达式)的上下文中转义为\\. )来自文件基本名称(没有(最后一个)文件扩展名的部分)。

    • 注意:不指定替换操作数等同于指定'' ,空字符串,导致匹配字符串被有效去除; 换句话说: ... -replace '\\.' 等同于... -replace '\\.', ''
  • + $_.Extension将原始扩展名附加到修改后的基本名称。


[1] -replace默认不区分大小写,所有 PowerShell 操作符都是; -ireplace只是明确说明了这一事实; 还有-creplace变体,其中c表示操作区分大小写

[2] 在单行字符串中; 多行字符串中, . 默认情况下不匹配\\n (换行符),尽管这可以通过正则表达式开头的内联匹配选项(?s)进行更改。

这是另一个利用 PowerShell 管道的解决方案(在测试将重命名的文件后删除-WhatIf )。

它还使用前瞻正则表达式来替换文件名中除最后一个点之外的所有内容。

Get-ChildItem -Recurse  `
    <# Only select files that have more than one '.' in their name #> `
    | Where-Object { ($_.Name.ToCharArray() | Where-Object {$_ -eq '.'} | Measure-Object ).Count -gt 1 } `
    `
    <# Change the location to the directory and rename so you don't have deal with the directory name #> `
    <# Also, use a lookahead regex to replace all but the last dot. #> `
    | ForEach-Object { Push-Location $_.Directory; Rename-Item $_ ($_.Name -replace "\.(?=.*?\.)", "") -Verbose -WhatIf; Pop-Location }

这是使用别名的相同命令的更简洁版本:

dir -r | ?{ ($_.Name.ToCharArray() | ?{ $_ -eq '.' } | measure ).Count -gt 1 } | %{ pushd $_.Directory; ren $_ ($_.Name -replace "\.(?=.*?\.)", "") -v -wh; popd }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM