2017-02-26 6 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(最初に列挙して、名前を変更したファイルが列挙を妨げないようにする)の間に、私はそれが_technically_必要であるとは思わない - 私の答えに追加した脚注を見てください。 – mklement0

答えて

4

TL; DR

は、あなただけの関心のファイルを処理することを確認してください:

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つの未満の文字を持っていたら[string]クラスの.Substring()方法はないので、あなたは、startIndex関連のエラーを取得します。文字列の長さを超えたインデックスを受け入れます(try 'ab'.Substring(3))。 すべて(非隠された)子項目を返しますので、あなたはフィルターなしでGet-ChildItemを実行していることから、前記

、あなたは無関係なファイルを処理することができる、名前が短すぎてもディレクトリ鉱石。

Cannot create a file when that file already exists.エラーが普通に効果的に空の文字列を返す新しい名前を返すスクリプトブロックに起因するエラーにフォローされているので、Rename-Itemはあなたが現在の名前にファイルの名前を変更することができないという不満をやや漠然とです。あなたも最初の実行、その最初の5つの文字を持つ、すなわちもし1つの以上の入力ファイル中にCannot create a file when that file already existsエラーを取得することができ、言っ

。切り落とされた結果は同じファイル名になります。

例えば、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 

3回目の実行時には、すべての名前が短すぎます。すべてはRename-Item : Cannot create a file when that file already exists.のエラーです。


[1]囲い(...)Get-ChildItemRename-Itemが呼び出される前に、一致するファイルは、アレイアップフロントに収集されることを保証します。
名前が変更されていないファイルがGet-ChildItemで再列挙されるのを明示的に防止し、反復を妨げます。しかし、の明示的な使用は、Get-ChildItemが、すべての名前が収集された後に本質的に可能である名前でソートされるので、always internally collects all files up front, across platformsという方法で実装されるため、技術的には必要ありません。あなたは
(...)ずに呼び出しが、同じに(...)かいけない機能量を使用しているかどうかというの光で
は、おそらくより多くのメモリ効率とわずかに速いです。

関連する問題