![](/img/trans.png)
[英]How to recursively change filenames for upper to lower case through bat file
[英]How to recursively truncate filenames in powershell?
我需要将文件名截断为 35 个字符(包括扩展名),所以我运行这个脚本,它适用于它自己的目录(PowerShell,Windows 10)。
Get-ChildItem *.pdf | rename-item -NewName {$_.name.substring(0,31) + $_.Extension}
然后我想应用相同的脚本,包括子目录:
Get-ChildItem -Recurse -Include *.pdf | Rename-Item -NewName {$_.Name.substring(0,31) + $_.Extension}
这个脚本给了我每个文件这样的错误:
Rename-Item : Error in input to script block for parameter 'NewName'. Exception when calling "Substring" with the arguments "2": "The index and length must reference a location in the string. Parameter name: length"
On line: 1 Character: 62
+ ... *.pdf | Rename-Item -NewName {$_.Name.substring(0,31) + $_.Extension}
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (C:\User\prsn..._file_name_long.pdf:PSObject) [Rename-Item], ParameterBindingException
+ FullyQualifiedErrorId : ScriptBlockArgumentInvocationFailed,Microsoft.PowerShell.Commands.RenameItemCommand
我试过这个,但在子目录上没有 go: 命令以 255 个字符截断所有文件名
我找到了这个,但没有答案: https://superuser.com/questions/1188711/how-to-recursively-truncate-filenames-and-directory-names-in-powershell
使用-replace
正则表达式运算符删除前 35 个字符之后的任何内容 - 它会简单地忽略任何不包含至少 35 个字符的字符串并按原样返回:
$_.Name -replace '(?<=^.{35}).*$'
我不认为你可以这样使用 $_ 。 我认为您必须将其包装在 ForEach 循环中才能使引用以这种方式工作。 完成后,您还必须指定要重命名的文件的路径:
就像是:
Get-ChildItem -Recurse -Include *.pdf -File |
ForEach-Object{
Rename-Item -Path $_.FullName -NewName ( $_.BaseName.SubString(0, 31) + $_.Extension )
}
请注意,我使用括号而不是花括号。 如果您使用脚本块,它可能无法评估。 还有其他方法可以实现,但我认为使用括号是最明显的。
请注意,我使用$_.BaseName
而不是名称。 基本名称不包括扩展名。 虽然我不知道你的子字符串是如何工作的,但我把它留给你决定。
您可以将其与@Mathias 的答案或对其进行一些修改相结合。 这可能会为您提供更好或更可靠的方法来派生新文件名。 我还没有测试它,但它可能看起来像:
Get-ChildItem -Recurse -Include *.pdf -File |
ForEach-Object{
Rename-Item -Path $_.FullName -NewName ( ($_.Name -replace '(?<=^.{35}).*$') + $_.Extension )
}
正确的错误信息是Exception calling "Substring" with "2" argument(s): "Index and length must refer to a location within the string.
原因是第二个参数大于文件名的长度。 例如"abc".Substring(0,4)
抛出。
$renameTarget = dir -File -Recurse *.pdf | ? { $_.Name.Length -gt 35 }
$renameTarget | Rename-Item -NewName {
$_.name.substring(0, 31) + ".pdf"
}
或者
dir *.pdf -File -Recurse | Rename-Item -NewName {
$_.name.substring(0, [Math]::Min($_.BaseName.length, 31)) + ".pdf"
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.