2016-03-27 13 views
1

私は、ファイルのリストを持っている:PowerShellの、項目の名前を変更使用して古い名前を置き換える機能

PS S:\temp> dir 


    Directory: S:\temp 


Mode    LastWriteTime  Length Name 
----    -------------  ------ ---- 
-a---   3/28/2016 2:07 AM   0 00001_asdfasdfsa df.txt 
-a---   3/28/2016 2:07 AM   0 00002_asdfasdfsa df - Copy (3).txt 
-a---   3/28/2016 2:07 AM   0 00003_asdfasdfsa df - Copy.txt 
-a---   3/28/2016 2:07 AM   0 00004_asdfasdfsa df - Copy (6).txt 
-a---   3/28/2016 2:07 AM   0 00005_asdfasdfsa df - Copy (5).txt 
-a---   3/28/2016 2:07 AM   0 00006_asdfasdfsa df - Copy (4).txt 
-a---   3/28/2016 2:07 AM   0 00007_asdfasdfsa df - Copy (2).txt 
-a---   3/28/2016 2:07 AM   0 700006_asdfasdfsa df - Copy (4) - Copy.txt 


PS S:\temp> 

は私が5つの数字と下線で始まるものをrenamemたいです。新しい名前は、それらのファイル名の先頭に指定した番号を追加します。私は10を追加した場合、新しい名前は次のようになります。

PS S:\temp> dir 


    Directory: S:\temp 


Mode    LastWriteTime  Length Name 
----    -------------  ------ ---- 
-a---   3/28/2016 2:07 AM   0 00011_asdfasdfsa df.txt 
-a---   3/28/2016 2:07 AM   0 00012_asdfasdfsa df - Copy (3).txt 
-a---   3/28/2016 2:07 AM   0 00013_asdfasdfsa df - Copy.txt 
-a---   3/28/2016 2:07 AM   0 00014_asdfasdfsa df - Copy (6).txt 
-a---   3/28/2016 2:07 AM   0 00015_asdfasdfsa df - Copy (5).txt 
-a---   3/28/2016 2:07 AM   0 00016_asdfasdfsa df - Copy (4).txt 
-a---   3/28/2016 2:07 AM   0 00017_asdfasdfsa df - Copy (2).txt 
-a---   3/28/2016 2:07 AM   0 700006_asdfasdfsa df - Copy (4) - Copy.txt 


PS S:\temp> 

今私のPowerShellのコードは次のとおりです。

dir * | ?{$_.name -match '^\d{5}_.+'} | Rename-Item -NewName {$_.name -replace '^(\d{5})(_.+)', ((([convert]::ToInt32('$1', 10) + 12).ToString("00000")) + '$2')} -whatif 

私は自分のコード内のエラーを見つけることができません。しかし、私はそれを実行すると、私は次のエラーメッセージが表示されます:

Rename-Item : The input to the script block for parameter 'NewName' failed. Exception calling "ToInt32" with "2" argument(s): "Could not find any recognizable digits." 
At line:1 char:62 
+ dir * | ?{$_.name -match '^\d{5}_.+'} | Rename-Item -NewName {$_.name -replace ' ... 
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
    + CategoryInfo   : InvalidArgument: (S:\temp\00001_asdfasdfsa df.txt:PSObject) [Rename-Item], ParameterBindingException 
    + FullyQualifiedErrorId : ScriptBlockArgumentInvocationFailed,Microsoft.PowerShell.Commands.RenameItemCommand 

私の質問は、どこが間違っていますか? replaceオペレータの交換部品に機能を使用しないでください。もしそうなら、-newname{}に複雑なロジックを書く方法は?ありがとう。

+1

置き換えがうまくいかなかったのは、-replaceが動作する理由によるものです。この回答を参照してください:http://stackoverflow.com/questions/8163061/passing-a-function-to-powershells-replace-function。基本的に '$ 1'は文字通り "$ 1"という文字列を意味し、正規表現エンジンはその文字列を手に入れません。 – Matt

答えて

1

-replaceを使用して、置換時にデータをマッサージすることはできません。リテラル文字列$1は整数に変換できないため、置換に失敗しました。同様の質問で述べたように、Passing a function to Powershell's (replace) functionでは、スクリプトブロックと.nNet正規表現静的メソッドReplaceを使用できます。

$replaceBlock = { 
    # Groups 0 contains the whole match. 1 is the first group... and so on. 
    ([convert]::ToInt32($args[0].Groups[1],10) + 12).ToString("00000") + $args[0].Groups[2] 
} 

Get-ChildItem | Where-Object{$_.name -match '^\d{5}_.+'} | Rename-Item -NewName { 
    [Regex]::Replace($_.name, '^(\d{5})(_.+)', $replaceBlock) 
} -whatif 

スクリプトブロックをインラインで使用することはできますが、それを取り出すことで、少しクリーンなコードにすることができます。しかし、私はおそらく-matchと返された$matchesオブジェクトを使用して同じことを行うでしょう。私はキャプチャグループを持っているwhere-objectを更新

Get-ChildItem | Where-Object{$_.name -match '^(\d{5})(_.+)'} | Rename-Item -NewName { 
    ([int]$Matches[1] + 12).ToString("00000") + $Matches[2] 
} -whatif 

注意。

+0

マットありがとうございます。 –

0

私は答えを得ました。

dir * | ?{$_.name -match '^\d{5}_.+'} | Rename-Item -NewName {(([convert]::toint32($_.name.substring(0, 5), 10) + 12).ToString("00000")) + $_.name.substring(5)} -whatif 

私は-newname{}ブロック内の任意のコードを使用できます。しかし、私はまだ私の-replace方法が機能しなかった理由を理解していない。

関連する問題