kch*_*hak 2 powershell rename-item-cmdlet
我有一堆以以下模式命名的jpg图像文件:
0001-rand01_012.jpg
0002-rand03_034.jpg
Run Code Online (Sandbox Code Playgroud)
我想通过删除前5个字符来重命名它们以获得表格:
rand01_012.jpg
Run Code Online (Sandbox Code Playgroud)
等等..
我使用以下命令:
Get-ChildItem | Rename-Item -NewName {$_.name.Substring(5)}
Run Code Online (Sandbox Code Playgroud)
当与-whatif标志一起使用时,我得到预期的消息:
Performing the operation "Rename File" on target "Item: C:\Users\xxxx\Documents\xx xx\temp2\0123-rand16_030.jpg Destination: C:\Users\
xxxx\Documents\xx xx\temp2\rand16_030.jpg".
Run Code Online (Sandbox Code Playgroud)
但是删除whatif
给我这种类型的错误:
Rename-Item : The input to the script block for parameter 'NewName' failed. Exception calling "Substring" with "1" argument(s): "startIndex cannot be
larger than length of string.
Run Code Online (Sandbox Code Playgroud)
其次是一堆:
Rename-Item : Cannot create a file when that file already exists.
Run Code Online (Sandbox Code Playgroud)
重命名文件本身时会删除随机数量的字符,而不是按预期的5个字符。所以他们最终像:
01.jpg
01.jpg
.
.
.
d14_001.jpg
Run Code Online (Sandbox Code Playgroud)
等等
过去,我已经使用此命令成功重命名了此类文件。我得到如此随机结果的事实使我拔头发。
tl; dr
确保只处理感兴趣的文件:
(Get-ChildItem -File [0-9][0-9][0-9][0-9]-*.jpg) |
Rename-Item -NewName {$_.name.Substring(5)}
Run Code Online (Sandbox Code Playgroud)
放置(...)
在技术上Get-ChildItem
不是必需的,但建议这样做。[1]
那样:
您可以排除不相关的文件。
即使出现问题,您也可以纠正问题并再次运行命令以仅处理失败的文件,而不会影响以前重命名的文件。
听起来您错误地重复运行了命令,所以您减少了5个字符。多次:
0001-rand01_01.jpg
-> rand01_01.jpg
->_01.jpg
文件名少于5个字符后,您将得到startIndex
-related错误,因为[string]
类的.Substring()
方法不接受超出字符串长度的索引(try 'ab'.Substring(3)
)。
就是说,由于您Get-ChildItem
没有过滤器就在运行,因此返回了所有(非隐藏的)子项,因此您可能正在处理不相关的文件或名称太短的目录。
这些Cannot create a file when that file already exists.
错误只是脚本错误导致的后续错误,这些脚本通常会正常返回新名称,并有效地返回空字符串,因此Rename-Item
,有些晦涩的抱怨是您无法将文件重命名为其当前名称。
就是说,您甚至可能Cannot create a file when that file already exists
在第一次运行时出错,即,如果有多个输入文件的前5个字符为1个字符。切掉的文件名相同。
例如,0001-rand01_012.jpg
和0002-rand01_012.jpg
都将重命名为rand01_012.jpg
,一旦第一个被重命名,它就会失败。
也就是说,为了使您的命令按预期工作,所有文件名都是由于删除前5个字符而产生的。必须是唯一的。
这是一个MCVE(最小,完整和可验证的示例):
设定:
# Create and change to temp dir.
Set-Location (mkdir temp)
# Create sample input files named 0001-rand01_01.jpg, 0002-rand01_02.jpg, ...
# Note how the suffixes after the first 5 char. must be *unique*.
1..9 | %{ $null > "000${_}-rand01_0${_}.jpg" }
Run Code Online (Sandbox Code Playgroud)
第一次运行:
# No errors
> (Get-ChildItem -File) | Rename-Item -NewName { $_.Name.Substring(5) }
# Show new names
> Get-ChildItem | Select Name
Name
----
rand01_01.jpg
rand01_02.jpg
rand01_03.jpg
rand01_04.jpg
rand01_05.jpg
rand01_06.jpg
rand01_07.jpg
rand01_08.jpg
rand01_09.jpg
Run Code Online (Sandbox Code Playgroud)
第二次运行产生:
Name
----
1_01.jpg
1_02.jpg
1_03.jpg
1_04.jpg
1_05.jpg
1_06.jpg
1_07.jpg
1_08.jpg
1_09.jpg
Run Code Online (Sandbox Code Playgroud)
在第3次运行时,所有名称都太短,您将得到的只是Rename-Item : Cannot create a file when that file already exists.
错误。
[1]围Get-ChildItem
中(...)
确保匹配文件在一个收集阵列,前场,前Rename-Item
被调用。
这明确地防止了已经重命名的文件被Get-ChildItem
迭代重新枚举,从而干扰了迭代。明确使用的(...)
是在技术上没有必要,因为Get-ChildItem
是实现在一个方式总是在内部收集的所有文件前面,跨平台的,因为它的名字,所有的名字已被收集之后本质上是唯一可能的排序。
在光,无论您使用(...)
与否应功能尽管(...)
建议使用,但数量相同,因为它不依赖于实现细节。