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

如何使用PowerShell从文件名中删除句点?,powershell,Powershell,我试图在PowerShell中编写一个脚本,在文件夹中搜索包含不必要句点的文件,然后mass从文件名中删除句点 例如,Example.File.doc-->ExampleFile.doc 每当我运行代码时,控制台都会返回以下内容:重命名项:无法将参数绑定到参数“NewName”,因为它是空字符串 有人知道问题是什么吗 提前感谢您的帮助 $files = get-childitem -path "C:\XXXX\XXXX\XXXX" -Recurse foreach($file in $file

我试图在PowerShell中编写一个脚本,在文件夹中搜索包含不必要句点的文件,然后mass从文件名中删除句点

例如,Example.File.doc-->ExampleFile.doc

每当我运行代码时,控制台都会返回以下内容:重命名项:无法将参数绑定到参数“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

这里有一些关于字符串替换的附加信息,仅供参考

这里还有一些其他问题。您应该通过包含-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

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

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

相配。正则表达式中的逐字字符,必须将其转义为\:

请注意,通常最好使用“…”引号,而不是。。。对于要逐字使用的正则表达式和字符串文本

然而:

这也将删除该选项。烧焦在文件扩展名中,这是不需要的

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

简洁的单管道解决方案:

注意:上面命令中的预览操作。删除-如果您确定该操作将执行您想要的操作,则删除

-文件限制匹配到文件而不是目录

-包含*.*限制与至少包含2个文件名的文件名匹配。查斯

通过将要重命名的文件直接从Get ChildItem管道化到rename Item,可以将-NewName参数指定为{…},它可以使用从Get ChildItem接收的实例的属性,从相应输入文件的名称动态派生新名称

$\.BaseName-替换“\.”将删除所有文字。查斯。逃逸为\。在从文件基名称对其进行操作的正则表达式的上下文中,不带最后文件扩展名的部件

注意:不指定替换操作数等同于指定空字符串,从而有效删除匹配的字符串;换句话说:-替换“\”与-替换“\”, +$\扩展名将原始扩展名附加到修改后的基名称

[1] -与所有PowerShell操作符一样,replace默认不区分大小写-ireplace只是把事实说得很清楚;还有-creplace变体,其中c表示操作区分大小写


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

下面是另一个利用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 }

放弃一个点的测试,只对所有文件名使用.Replace'.'方法,会更干净吗?如果没有圆点可替换,该方法将毫无用处。。。这可能不太明显。[皱眉]我拿不定主意。这里的关键是-match-and-replace操作符支持正则表达式,你需要避开像句号这样的元字符。我很感谢你的反馈,Glenn。
Get-ChildItem -File -Path "C:\XXXX\XXXX\XXXX" -Recurse -Include *.*.* | 
  Rename-Item -NewName { ($_.BaseName -replace '\.') + $_.Extension } -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 }