Te reguły zostały odkryte po długich testach na komputerze z systemem Vista. Nie przeprowadzono testów z unicode w nazwach plików.
RENAME wymaga 2 parametrów - sourceMask, a następnie targetMask. Zarówno sourceMask jak i targetMask mogą zawierać znaki wieloznaczne *
i/lub ?
. Zachowanie symboli wieloznacznych zmienia się nieznacznie pomiędzy maskami źródłowymi i docelowymi.
Note - REN może być użyte do zmiany nazwy folderu, ale symbole wieloznaczne nie są dozwolone w masce źródłowej ani docelowej podczas zmiany nazwy folderu. Jeśli sourceMask pasuje do co najmniej jednego pliku, wówczas nazwa pliku(ów) zostanie zmieniona, a foldery zostaną zignorowane. Jeśli sourceMask pasuje tylko do folderów, a nie do plików, wówczas generowany jest błąd składni, jeśli w źródle lub celu pojawią się symbole wieloznaczne. Jeśli sourceMask nie pasuje do niczego, to zostanie wyświetlony błąd “nie znaleziono pliku”.
Ponadto, podczas zmiany nazwy plików, symbole wieloznaczne są dozwolone tylko w części nazwy pliku w sourceMask. Znaki wieloznaczne nie są dozwolone w ścieżce prowadzącej do nazwy pliku.
sourceMask
Maska sourceMask działa jako filtr określający, które pliki są zmieniane. Znaki wieloznaczne działają tu tak samo jak w każdej innej komendzie filtrującej nazwy plików.
?
- Dopasowuje dowolny 0 lub 1 znak z wyjątkiem .
Ten symbol wieloznaczny jest zachłanny - zawsze pochłania następny znak, jeśli nie jest to .
Jednak nie dopasuje niczego bez porażki, jeśli na końcu nazwy lub jeśli następny znak jest .
*
- Dopasowuje dowolne 0 lub więcej znaków włączając .
(z jednym wyjątkiem poniżej). Ten symbol wieloznaczny nie jest zachłanny. Dopasuje tak mało lub tak dużo, jak jest to potrzebne, by umożliwić dopasowanie kolejnych znaków.
Wszystkie znaki niezawierające znaków wieloznacznych muszą pasować same do siebie, z kilkoma specjalnymi wyjątkami.
.
- Dopasowuje się samo lub może dopasować koniec nazwy (nic), jeśli nie pozostało więcej znaków. (Uwaga - prawidłowa nazwa Windows nie może kończyć się na .
)
{space}
- Dopasowuje się lub może dopasować koniec nazwy (nic), jeśli nie pozostanie więcej znaków. (Uwaga - poprawna nazwa Windows nie może kończyć się na {space}
)
*.
na końcu - Dopasowuje dowolne 0 lub więcej znaków z wyjątkiem .
Kończące .
może być w rzeczywistości dowolną kombinacją .
i {space}
tak długo, jak ostatnim znakiem w masce jest .
Jest to jedyny wyjątek, gdzie *
nie dopasowuje po prostu dowolnego zestawu znaków.
Powyższe reguły nie są zbyt skomplikowane. Ale jest jeszcze jedna bardzo ważna reguła, która sprawia, że sytuacja staje się zagmatwana: SourceMask jest porównywane zarówno z długą nazwą, jak i z krótką nazwą 8.3 (jeśli istnieje). Ta ostatnia reguła może bardzo utrudnić interpretację wyników, ponieważ nie zawsze jest oczywiste, kiedy maska jest dopasowywana poprzez nazwę krótką.
Możliwe jest użycie RegEdit do wyłączenia generowania krótkich nazw 8.3 na woluminach NTFS, w którym to momencie interpretacja wyników maski plików jest znacznie prostsza. Wszystkie krótkie nazwy, które zostały wygenerowane przed wyłączeniem krótkich nazw, pozostaną.
targetMask
Uwaga - nie przeprowadziłem żadnych rygorystycznych testów, ale wydaje się, że te same zasady działają również dla nazwy docelowej polecenia COPY
Maska docelowa określa nową nazwę. Jest ona zawsze stosowana do pełnej długiej nazwy; The targetMask nigdy nie jest stosowana do krótkiej nazwy 8.3, nawet jeśli sourceMask pasowało do krótkiej nazwy 8.3.
Obecność lub brak znaków wieloznacznych w masce źródłowej nie ma wpływu na sposób przetwarzania znaków wieloznacznych w masce docelowej.
W poniższej dyskusji - c
reprezentuje każdy znak, który nie jest *
, ?
, lub .
Maska docelowa jest przetwarzana względem nazwy źródłowej ściśle od lewej do prawej, bez cofania się.
c
- Przesuwa pozycję w nazwie źródłowej tylko jeśli znak źródłowy nie jest .
, i zawsze dołącza c
do nazwy docelowej. (Zastępuje znak, który był w źródle znakiem c
, ale nigdy nie zastępuje .
)
?
- Dopasowuje następny znak z długiej nazwy źródłowej i dołącza go do nazwy docelowej tak długo, jak długo znakiem źródłowym nie jest .
Jeśli następny znak jest .
lub na końcu nazwy źródłowej, to żaden znak nie jest dodawany do wyniku i bieżąca pozycja w nazwie źródłowej pozostaje niezmieniona.
*
na końcu targetMask - Dodaje wszystkie pozostałe znaki ze źródła do celu. Jeśli jest już na końcu źródła, to nie robi nic.
*c
- Dopasowuje wszystkie znaki źródła od bieżącej pozycji do ostatniego wystąpienia c
(dopasowywanie z uwzględnieniem wielkości liter) i dołącza dopasowany zestaw znaków do nazwy celu. Jeśli c
nie zostanie znalezione, to dołączane są wszystkie pozostałe znaki ze źródła, a następnie c
Jest to jedyna znana mi sytuacja, w której dopasowywanie wzorców plików Windows uwzględnia wielkość liter.
*.
- Dopasowuje wszystkie znaki źródłowe od bieżącej pozycji do ostatniego wystąpienia .
(dopasowanie zachłanne) i dołącza dopasowany zestaw znaków do nazwy docelowej. znaków do nazwy docelowej. Jeśli .
nie zostanie znalezione, to dołączane są wszystkie pozostałe znaki ze źródła, a następnie .
*?
- Dołącza wszystkie pozostałe znaki ze źródła do nazwy docelowej. Jeśli jest już na końcu źródła, to nie robi nic.
.
bez *
z przodu - Przesuwa pozycję w źródle o pierwsze wystąpienie .
bez kopiowania żadnych znaków, i dołącza .
do nazwy docelowej. Jeśli .
nie znajduje się w źródle, to przesuwa się na koniec źródła i dołącza .
do nazwy celu.
Po wyczerpaniu targetMask, wszelkie kończące się .
i {space}
są obcinane z końca wynikowej nazwy docelowej, ponieważ nazwy plików Windows nie mogą kończyć się .
lub {space}
Kilka praktycznych przykładów
Zastąp znak na 1. i 3. pozycji przed jakimkolwiek rozszerzeniem (dodaje drugi lub trzeci znak, jeśli jeszcze nie istnieje)
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
Zmienia (końcowe) rozszerzenie każdego pliku
ren * *.txt
a -> a.txt
b.dat -> b.txt
c.x.y -> c.x.txt
Dodaje rozszerzenie do każdego pliku
ren * *?.bak
a -> a.bak
b.dat -> b.dat.bak
c.x.y -> c.x.y.bak
Usuwa dodatkowe rozszerzenie po rozszerzeniu początkowym. Zauważ, że odpowiednie ?
musi być użyte, aby zachować pełną istniejącą nazwę i początkowe rozszerzenie.
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)
To samo co powyżej, ale filtruje pliki z początkową nazwą i/lub rozszerzeniem dłuższym niż 5 znaków, aby nie zostały obcięte. (Oczywiście można dodać dodatkowe ?
na obu końcach targetMask, aby zachować nazwy i rozszerzenia o długości do 6 znaków)
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)
Zmień znaki po ostatnim _
w nazwie i spróbuj zachować rozszerzenie. (Nie działa poprawnie, jeśli _
występuje w rozszerzeniu)
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)
Dowolna nazwa może być podzielona na części składowe, które są ograniczone przez .
Znaki mogą być dodawane lub usuwane tylko z końca każdej części składowej. Znaki nie mogą być usuwane lub dodawane na początku lub w środku składnika przy jednoczesnym zachowaniu reszty za pomocą symboli wieloznacznych. Substytucje są dozwolone wszędzie.
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
Jeśli włączone są krótkie nazwy, to sourceMask z co najmniej 8 ?
dla nazwy i co najmniej 3 ?
dla rozszerzenia będzie pasować do wszystkich plików, ponieważ zawsze będzie pasować do krótkiej nazwy 8.3.
ren ????????.??? ?x.????999.*rForTheCourse
part1.part2.part3.part4 -> px.part999.part3.parForTheCourse
Przydatna sztuczka/błąd? do usuwania prefiksów nazw
Ten post SuperUser opisuje jak zestaw ukośników (/
) może być użyty do usunięcia wiodących znaków z nazwy pliku. Jeden ukośnik jest wymagany dla każdego znaku, który ma zostać usunięty. Potwierdziłem to zachowanie na maszynie z systemem Windows 10.
ren "abc-*.txt" "////*.txt"
abc-123.txt --> 123.txt
abc-HelloWorld.txt --> HelloWorld.txt
Ta technika działa tylko wtedy, gdy zarówno maska źródłowa, jak i docelowa są ujęte w cudzysłów. Wszystkie poniższe formularze bez wymaganych cudzysłowów zawodzą z tym błędem: The syntax of the command is incorrect
REM - All of these forms fail with a syntax error.
ren abc-*.txt "////*.txt"
ren "abc-*.txt" ////*.txt
ren abc-*.txt ////*.txt
The /
cannot be used to remove any characters in the middle or end of a file name. Może on jedynie usunąć znaki wiodące (prefiks). Zauważ również, że ta technika nie działa z nazwami folderów.
Technicznie rzecz biorąc, /
nie działa jako symbol wieloznaczny. Raczej wykonuje proste podstawianie znaków, ale po podstawieniu, polecenie REN rozpoznaje, że /
nie jest poprawne w nazwie pliku i usuwa z nazwy wiodące ukośniki /
. REN podaje błąd składni, jeśli wykryje /
w środku nazwy docelowej.
Możliwy błąd RENAME - jedna komenda może zmienić nazwę tego samego pliku dwa razy!
Rozpoczynamy w pustym folderze testowym:
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
Wierzę, że sourceMask *1*
najpierw dopasowuje długą nazwę pliku, a plik zostaje przemianowany na oczekiwany wynik 223456789.123.x
. RENAME następnie kontynuuje poszukiwanie kolejnych plików do przetworzenia i znajduje nowo nazwany plik poprzez nową krótką nazwę 223456~1.X
. Następnie nazwa pliku jest zmieniana ponownie, dając ostateczny wynik 223456789.123.xx
.
Jeśli wyłączę generowanie nazw w 8.3, wtedy RENAME daje oczekiwany rezultat.
Nie rozpracowałem do końca wszystkich warunków wyzwalających, które muszą istnieć, aby wywołać to dziwne zachowanie. Obawiałem się, że może być możliwe stworzenie niekończącej się rekursywnej RENAME, ale nigdy nie udało mi się jej wywołać.
Uważam, że wszystkie poniższe warunki muszą być prawdziwe, aby wywołać błąd. Każdy przypadek błędu, który widziałem miał następujące warunki, ale nie wszystkie przypadki, które spełniały poniższe warunki były błędne.
- Krótkie nazwy 8.3 muszą być włączone
- The sourceMask musi pasować do oryginalnej długiej nazwy.
- Początkowa zmiana nazwy musi wygenerować nazwę krótką, która również pasuje do sourceMask
- Początkowa zmieniona nazwa krótka musi sortować później niż oryginalna nazwa krótka (jeśli istniała?)