繁体   English   中英

如何递归截断 powershell 中的文件名?

[英]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.

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