2017-02-26 42 views
2

我有一堆在下面的模式命名的JPG圖片文件不起作用:PowerShell中,重命名項如預期

0001-rand01_012.jpg 
0002-rand03_034.jpg 

我想通過去除前5個字符來獲得的形式將其重命名:

rand01_012.jpg 

等。

我用下面的命令:

Get-ChildItem | Rename-Item -NewName {$_.name.Substring(5)} 

當使用這種帶-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". 

但去除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. 

後面是一大堆:

Rename-Item : Cannot create a file when that file already exists. 

本身更名去掉,而不是5中之意字符的隨機數的文件。因此,他們已經結束了,如:

01.jpg 
01.jpg 
. 
. 
. 
d14_001.jpg 

我已經使用這個命令與成功的過去重命名這些文件。我得到這樣隨機結果的事實讓我把頭髮拉出來。

+0

'(Get-ChildItem)| Rename-Item -NewName {$ _。Name.Substring(5)}' –

+0

對不起,爲什麼它會改變行爲? – 4c74356b41

+0

@ 4c74356b41:在將該數組傳遞給'Rename-Item'之前,它首先顯式地收集數組中的所有匹配文件。但是,雖然這使得_conceptual_ sense(首先枚舉,以便重命名的文件不會干擾枚舉),但我不認爲這是必要的 - 請參閱我添加到我的答案中的腳註。 – mklement0

回答

4

TL;博士

確保只處理感興趣的文件:

Get-ChildItem -File [0-9][0-9][0-9][0-9]-*.jpg | Rename-Item -NewName {$_.name.Substring(5)} 

您可以選擇將(...)各地Get-ChildItem測序的清晰度,但是這不是絕對必要的。 [1]

這樣:

  • 您排除不相關的文件前面。

  • 即使出現問題,您也可以更正問題並再次運行該命令,以僅重新處理失敗的文件,而不影響以前重命名的文件。

    • 的東西去錯了最可能的原因是導致相同文件名去掉5第一個字符經過1個多輸入文件。

這聽起來像您不慎運行此命令反覆,所以你剪了5個字符。多次

0001-rand01_01.jpg - >rand01_01.jpg - >_01.jpg

一旦一個文件名有少於5個字符,你會得到的startIndex - 相關錯誤,因爲[string]類的.Substring()方法沒有。接受超出字符串長度的索引(嘗試'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錯誤,即如果超過1個輸入文件,它的第一個5個字符。切斷結果在相同的文件名。

例如,0001-rand01_012.jpg0002-rand01_012.jpg都將被重新命名爲rand01_012.jpg,這失敗一旦第一個已被重命名。

也就是說,讓您的命令按照預期工作,所有文件名都是由於丟棄前5個字符而產生的。必須是唯一的。

下面是一個MCVE (Minimal, Complete, and Verifiable Example)

設置:

# 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" } 

第一次運行:

# 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 

一個第二次運行產量:

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 

在第三次運行的時候,所有的名字都太短了,你會得到的是Rename-Item : Cannot create a file when that file already exists.錯誤。


[1]圍Get-ChildItem(...)確保匹配的文件被收集在一個陣列前面,被調用之前Rename-Item
這明確防止已重命名的文件被Get-ChildItem重新枚舉,從而干擾迭代;然而,明確使用(...)在技術上沒有必要,因爲Get-ChildItemalways internally collects all files up front, across platforms的方式實現,因爲它按名稱對它們進行排序,這在名稱被收集後本質上是唯一可能的。
在的光,無論你用(...)應不應該功能量相同,儘管調用沒有(...)可能是更多的內存效率和速度稍快。