5

私は PowerShell を初めて使用し、最近フォルダー内の 120 個のファイルの名前を変更しようとすると、奇妙な動作が発生します。

私が持っているのは、0001.txt、0002.txt、... 0120.txt の合計 120 個のファイルという名前のファイルです。各ファイル名の前に「a」を追加したい。私はこのコマンドを思いつきました:

ls | ren -newname {$_.name -replace '(\d+)','a$1'}

しかし、実行後、次のような多数のエラーが発生します。

「指定されたパス、ファイル名、またはその両方が長すぎます。完全修飾ファイル名は 260 未満でなければなりません」

そして、自分のフォルダーを調べると、取得するのはファイル名だけです

aaaaaaaaaaaaaaaaaaaaaaaaa(repeat until it hit system limit on path length)....a0001.txt
...
...
...
aaaaaaaaaaaaaaaaaaaaaaaaa(repeat until it hit system limit on path length)....a0120.txt

-cf スイッチを使用してさらに調べたところ、PowerShell が名前変更プロセスを再帰的に試行していることがわかりました。120 個のファイルすべての名前を変更する最初のパスの後、コマンドを a0001.txt に再度適用し、ファイル名の前に別の「a」を効果的に追加しました。そして、これはパスの長さの制限に達してエラーを報告するまで続きました。

私の名前変更コマンドに何か問題があるかどうか、誰か教えてもらえますか?

4

3 に答える 3

5

Foreach-Object (省略形%{ } ) にパイプして、ファイルの名前を一括変更します。各ファイル名の先頭に文字aを追加するだけの場合は、正規表現は必要ありません。必要なのは次のとおりです。

Get-ChildItem | %{Rename-Item $_ ('a' + $_.name)}

好みのエイリアスを使用する:

ls | %{ren $_ ('a' + $_.name)}

正規表現でそれを行うには、 use を使用する方が簡単です($_.name -replace '^','a')。正規表現を使用する理由が、ディレクトリに他のファイルがあり、数字の文字列と.txt拡張子で名前が付けられたファイルの名前のみを変更することである場合、使用している正規表現は任意の文字列の先頭にaを追加することに注意してください。連続した数字の。たとえば、agent007.txtの名前はagenta007.txtに変更されます。正規表現は、必要な形式のみに一致させる必要があります: '^(\d+)\.txt'.

また、-NewName引数で正規表現置換を使用することにより、正規表現に一致しない各ファイルの名前を、既に持っている同じ名前に変更していることにも注意してください。120 個のファイルでは大したことではありませんが、事前にファイル リストをフィルター処理します。

Get-ChildItem | ?{$_ -match '^(\d+)\.txt'} | %{Rename-Item $_ ('a' + $_.name)}

更新: PowerShell 3.0 には、特定の条件下で一括ファイル名変更が失敗する可能性があるバグがあるようです。ディレクトリ リストをRename-Itemにパイプすることによってファイルの名前が変更された場合、現在の名前よりもアルファベット順で大きい名前に名前が変更されたファイルは、後でディレクトリ リストに表示される新しい名前で再処理されます。これにより、フル パスの長さが最大 ​​260 文字を超えてエラーがスローされるまで、同じファイルの名前が繰り返し変更される可能性があります。

たとえば、文字aが先頭ではなく末尾に追加されても問題はないことに注意してください。これは、任意の数のファイルに対して機能します。

Get-ChildItem | %{Rename-Item $_ ($_.name + 'a')}

ファイルの名前がb0001b0002などで、先頭に文字aが追加されている場合、再処理の繰り返しは発生しません。ただし、文字cが先頭に追加されている場合は発生します。

次のコマンドは、すべての名前がbで始まる場合、任意の数のファイルの先頭に単一の aを追加します。

Get-ChildItem | %{Rename-Item $_ ('a' + $_.name)}

名前がbで始まる同じファイルを指定すると、次のコマンドは、長さの制限に達するまで文字cを前に繰り返し追加します。

Get-ChildItem | %{Rename-Item $_ ('c' + $_.name)}

これは、特定の数以上のファイルを含むリストでのみ発生します。OPは、ファイルの数を20未満に減らしても問題はないと言いました。しきい値は37であることがわかりました(36ファイル以下では、再処理は行われません)。この数が該当するすべてのケースで同じなのか、それともより具体的な要因によるものなのかはまだ判断できていません。

これについては後で詳しく説明し、この問題のパラメータをより具体的に特定したら、Microsoft にバグ レポートを提出します。

回避策:新しいファイル名が除外されるように、Where-Objectを使用してGet-ChildItemからリストをフィルター処理します。更新セクションの前の上記のコマンドの最後のバージョンは、PowerShell 3.0 で機能します。おそらく、名前が変更されたファイルは新しい名前でパイプラインに再導入され、もう一度処理されますが、新しい名前がフィルターと一致しないため、パイプラインを介した 2 回目のパスでは名前が変更されず、再処理されません。?{$_ -match '^(\d+)\.txt'}

于 2013-08-18T16:52:29.103 に答える