我有很多文件夹包含图像文件,这些文件意外地保存时没有扩展名。我设法弄清楚如何添加扩展名:
ls -file | ? {$_.extension -eq ''} | % {ren $_ ($_.name + '.jpeg')}
...但我不知道如何让它应用于所有子文件夹。
此命令不起作用:
Get-ChildItem -Recurse ls -file | ? {$_.extension -eq ''} | % {ren $_ ($_.name + '.jpeg')}
请问我哪里做错了吗?
首先,确保
ls
从中删除Get-ChildItem -Recurse ls -file
-ls
是 的别名Get-ChildItem
,并且由于您已经指定了 cmdlet 名称,PowerShell 将尝试找到名为 的文件夹ls
并从那里开始搜索。其次,不要将(别名)作为位置参数传递
$_
给它,而是通过管道传递它:Rename-Item
ren
通过管道将整个文件信息对象传输到允许 PowerShell 将正确的绝对
Rename-Item
路径绑定到文件系统对象,然后它将开始处理嵌套文件夹中的文件。Mathias 的回答很有帮助,很好地解释了这个问题并提供了有效的解决方案。
Rename-Item
给脚本块({ ... }
)-NewName
是一个延迟绑定脚本块的实例。为了增加性能改进,请执行以下操作:
为了递归地查找所有无扩展名的文件,您可以替换:
和:
其性能要好得多,因为过滤发生在源头(低级文件系统 API),而不是事后通过
Where-Object
(其内置别名为?
和where
)。笔记:
*.
仅匹配无扩展名的文件依赖于参数的遗留怪癖-Filter
。-Filter
通配符语法与PowerShell 的通配符表达式不同;值得注意的是,它不适用于仅支持 PowerShell通配符的/参数。*.
Get-ChildItem
-Include
-Exclude
虽然在这种情况下很有帮助,但是所支持的通配符语法的不一致性
-Filter
是潜在的陷阱;值得注意的是,它并不-Filter *.*
将匹配限制在具有扩展名的文件上;它匹配所有文件,并且实际上是多余的。*.*
合理地仅匹配具有扩展名的文件,但有一些注意事项:-Include
和的使用-Exclude
有其自身的缺陷 - 请参阅本答案的底部部分。Where-Object
方法一样,过滤是在事后执行的(枚举所有文件然后进行过滤),所以它比-Filter
使用慢得多。关于过滤的底线是
Get-ChildItem
:使用
-Filter
以获得最佳性能,但要注意它的怪癖,请参阅此答案了解概述。-Include
如果您需要支持多种模式和/或无怪癖语法和/或扩展功能,即使用字符集和范围,请使用,但请注意不使用[...]
时的违反直觉的行为- 请参阅此答案的底部部分。-Recurse
用于
Where-Object
后过滤,如果您需要执行比通配符表达式所能提供的更复杂的过滤;例如,在传递给的脚本块内Where-Object
,您可以使用正则表达式进行匹配。