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