これらのルールは、Vistaマシンでの広範なテストの後に発見されました。
RENAMEでは、2つのパラメータ、sourceMaskとtargetMaskの後に続く2つのパラメータが必要です。sourceMaskとtargetMaskの両方に*
および/または?
のワイルドカードを含めることができます。ワイルドカードの動作は、ソースマスクとターゲットマスクで若干異なります。
Note - REN を使用してフォルダの名前を変更することができますが、フォルダの名前を変更する際には、sourceMask または targetMask のどちらにもワイルドカードを使用することはできません。sourceMask が少なくとも 1 つのファイルに一致する場合、そのファイルはリネームされ、フォルダは無視されます。sourceMask がファイルではなくフォルダのみに一致する場合、source または target にワイルドカードが出現すると構文エラーが発生します。sourceMask が何もマッチしない場合は、"file not found" エラーが発生します。
_また、ファイルの名前を変更する際に、ワイルドカードは sourceMask のファイル名部分でのみ許可されます。
sourceMask
sourceMaskは、どのファイルがリネームされるかを決定するためのフィルタとして機能します。ワイルドカードは、ファイル名をフィルタリングする他のコマンドと同じように機能します。
?
- 0x6以外の0文字または1文字にマッチします。このワイルドカードは貪欲です。このワイルドカードは貪欲ではありません。後続の文字がマッチするようにするために必要な分だけマッチします。
ワイルドカード以外のすべての文字は、いくつかの特殊なケースの例外を除いて、それ自身と一致しなければなりません。
.
- 自分自身にマッチするか、それ以上の文字が残っていない場合は名前の最後にマッチします(何もありません)。(注 - 有効なWindows名は.
で終わることはできません)
.
- それ自身にマッチするか、それ以上の文字が残らない場合は名前の最後にマッチします(何もありません)。(注意 - 有効なWindows名は*
で終わることはできません)
.
at the end - 0個以上の文字にマッチします _ただし、.
を除く) .
で終わる{space}
は、マスクの最後の文字が{space}
である限り、実際には*.
と.
の任意の組み合わせになります。
上記のルールはそれほど複雑ではありません。しかし、状況を混乱させる非常に重要なルールがもう一つあります。それは、sourceMaskは長い名前と短い8.3の名前(存在する場合)の両方と比較されるということです。この最後のルールは結果の解釈を非常にトリッキーなものにします。
RegEdit を使って NTFS ボリューム上での 8.3 のショートネームの生成を無効にすることができます。ショートネームを無効にする前に生成されたショートネームはすべて残ります。
targetMask
注 - 厳密なテストはしていませんが、COPYコマンドのターゲット名にも同じルールが適用されるようです
targetMaskは新しい名前を指定します。targetMaskは常に完全なロングネームに適用されます。
sourceMask にワイルドカードがあってもなくても、targetMask でのワイルドカードの処理方法には影響しません。
以下の議論では - .
は .
、{space}
、.
、*
以外の文字を表します。
targetMask はソース名に対して厳密に左から右に処理され、バックトラッキングは行われません。
c
- ソース文字が *
でない場合にのみソース名内の位置を進め、常にターゲット名に ?
を追加します。(ソースにあった文字を .
に置き換えますが、c
は置き換えません)
.
- ソースのロングネームから次の文字をマッチさせ、ソースの文字が c
でない限り、それをターゲット名に追加します。
c
at the end of targetMask - ソースの残りの文字をすべてターゲットに追加します。すでにソースの最後にある場合は何もしません。
.
- 現在の位置から最後に ?
が出現するまでのすべてのソース文字をマッチさせ (大文字小文字を区別する貪欲なマッチ)、マッチした文字セットをターゲット名に追加します。.
が見つからない場合、ソースからの残りの文字がすべて追加され、その後に.
が追加されます。これは、Windowsのファイルパターンマッチングが大文字小文字を区別する唯一の状況です。
*
- 現在の位置から *c
が最後に出現するまでのすべてのソース文字にマッチします (貪欲なマッチ)。文字をターゲット名に追加します。c
が見つからない場合は、ソースからの残りの文字をすべて追加し、c
c
- ソースからの残りの文字をすべてターゲットに追加します。すでにソースの最後にある場合は何もしません。
*.
の前に .
がない場合 - ソース内の位置を .
の最初の文字をコピーせずに前に進め、ターゲット名に .
を追加します。*?
がソースにない場合は、ソースの最後まで進み、ターゲット名に .
を追加します。
targetMask を使い切った後。Windows のファイル名は *
または .
いくつかの実用的な例
拡張子の前の 1 番目と 3 番目の位置にある文字を代入します。(まだ存在しない場合は2文字目か3文字目を追加)
ren * A?Z*
1 -> AZ
12 -> A2Z
1.txt -> AZ.txt
12.txt -> A2Z.txt
123 -> A2Z
123.txt -> A2Z.txt
1234 -> A2Z4
1234.txt -> A2Z4.txt
全てのファイルの(最終的な)拡張子を変更する
ren * *.txt
a -> a.txt
b.dat -> b.txt
c.x.y -> c.x.txt
全てのファイルに拡張子を追加する
ren * *?.bak
a -> a.bak
b.dat -> b.dat.bak
c.x.y -> c.x.y.bak
最初の拡張子の後の余分な拡張子を削除する。既存の完全な名前と最初の拡張子を保持するためには、適切な .
を使用しなければならないことに注意してください。
ren * ?????.?????
a -> a
a.b -> a.b
a.b.c -> a.b
part1.part2.part3 -> part1.part2
123456.123456.123456 -> 12345.12345 (note truncated name and extension because not enough `?` were used)
上記と同じだが、最初の名前や拡張子が5文字より長いファイルをフィルタリングして、切り捨てられないようにする。(明らかに6文字までの名前と拡張子を保存するために、targetMaskの両端に.
を追加することができます)
ren ?????.?????.* ?????.?????
a -> a
a.b -> a.b
a.b.c -> a.b
part1.part2.part3 -> part1.part2
123456.123456.123456 (Not renamed because doesn't match sourceMask)
名前の最後の.
以降の文字を変更し、拡張子を保存しようとします。
ren *_* *_NEW.*
abcd_12345.txt -> abcd_NEW.txt
abc_newt_1.dat -> abc_newt_NEW.dat
abcdef.jpg (Not renamed because doesn't match sourceMask)
abcd_123.a_b -> abcd_123.a_NEW (not desired, but no simple RENAME form will work in this case)
どんな名前でも、0x6で区切られたコンポーネントに分割することができます& 文字は、各コンポーネントの末尾にのみ追加または削除することができます。ワイルドカードを使用して残りの部分を保存しながら、コンポーネントの先頭または中間に文字を削除したり、追加したりすることはできません。置換はどこでも可能です。
ren ??????.??????.?????? ?x.????999.*rForTheCourse
part1.part2 -> px.part999.rForTheCourse
part1.part2.part3 -> px.part999.parForTheCourse
part1.part2.part3.part4 (Not renamed because doesn't match sourceMask)
a.b.c -> ax.b999.crForTheCourse
a.b.CarPart3BEER -> ax.b999.CarParForTheCourse
短縮名が有効になっている場合、名前に少なくとも 8 .
、拡張子に少なくとも 3 {space}
を指定した sourceMask は、常に 8.3 の短縮名と一致するため、すべてのファイルにマッチします。
ren ????????.??? ?x.????999.*rForTheCourse
part1.part2.part3.part4 -> px.part999.part3.parForTheCourse
名前の接頭辞を削除するための便利な癖/バグ?
この SuperUser の投稿 は、ファイル名から先頭の文字を削除するためにフォワードスラッシュ (.
) のセットを使用する方法を説明しています。削除する文字1文字につき、1つのスラッシュが必要です。Windows10のマシンで動作を確認してみました。
ren "abc-*.txt" "////*.txt"
abc-123.txt --> 123.txt
abc-HelloWorld.txt --> HelloWorld.txt
REM - All of these forms fail with a syntax error.
ren abc-*.txt "////*.txt"
ren "abc-*.txt" ////*.txt
ren abc-*.txt ////*.txt
この手法は、ソースマスクとターゲットマスクの両方が二重引用符で囲まれている場合にのみ動作します。必要な引用符がない以下のフォームはすべてこのエラーで失敗します。{space}
C:\test>copy nul 123456789.123
1 file(s) copied.
C:\test>dir /x
Volume in drive C is OS
Volume Serial Number is EE2C-5A11
Directory of C:\test
09/15/2012 07:42 PM <DIR> .
09/15/2012 07:42 PM <DIR> ..
09/15/2012 07:42 PM 0 123456~1.123 123456789.123
1 File(s) 0 bytes
2 Dir(s) 327,237,562,368 bytes free
C:\test>ren *1* 2*3.?x
C:\test>dir /x
Volume in drive C is OS
Volume Serial Number is EE2C-5A11
Directory of C:\test
09/15/2012 07:42 PM <DIR> .
09/15/2012 07:42 PM <DIR> ..
09/15/2012 07:42 PM 0 223456~1.XX 223456789.123.xx
1 File(s) 0 bytes
2 Dir(s) 327,237,562,368 bytes free
REM Expected result = 223456789.123.x
?
は、ファイル名の途中や末尾の文字を削除するためには使用できません。削除できるのは、先頭の文字(プレフィックス)のみです。また、このテクニックはフォルダ名には使えないことに注意してください。
厳密には、?
はワイルドカードとして機能していません。むしろ、単純な文字置換を行っていますが、置換後、RENコマンドは_
がファイル名では無効であることを認識し、先頭の_
スラッシュをファイル名から削除します。REN は、対象の名前の途中に .
があることを検出すると、構文エラーを与えます。
RENAMEのバグの可能性 - 1つのコマンドで同じファイルの名前を2回変更することがあります!
空のテストフォルダで起動。
0x1&
sourceMask ?
が最初に長いファイル名にマッチし、ファイルは期待される ?
の結果にリネームされると思います。その後、RENAMEは処理するファイルを探し続け、新しいショートネーム/
を介して新たに命名されたファイルを見つけます。その後、ファイルは再びリネームされ、最終的な結果はThe syntax of the command is incorrect
となります。
8.3の名前生成を無効にすると、RENAMEでは期待通りの結果が得られます。
この奇妙な動作を引き起こすために存在しなければならないトリガー条件の全てを完全に理解したわけではありません。終わらない再帰的なRENAMEを作成できるのではないかと心配していましたが、それを誘発することはできませんでした。
私は、このバグを誘発するためには、以下のすべてが真でなければならないと考えています。私が見たバグったケースはすべて以下の条件を満たしていましたが、以下の条件を満たしているケースがすべてバグったわけではありませんでした。
- 8.3のショートネームが有効になっている必要がある
- sourceMaskが元のロングネームと一致している必要がある。
- 最初のリネームは、ソースマスクにもマッチするショートネームを生成しなければならない
- 最初にリネームされたショートネームは、元のショートネームよりも後にソートされなければならない (存在する場合は?)