Reguły te zostały odkryte po szeroko zakrojonych testach na komputerze z systemem Vista. Nie przeprowadzono testów z użyciem Unicode w nazwach plików.
RENAME wymaga 2 parametrów - maska SourceMask, a następnie maska docelowa. Zarówno sourceMask, jak i targetMask mogą zawierać *
i / lub ?
symbole wieloznaczne. Zachowanie symboli wieloznacznych zmienia się nieznacznie między maskami źródłowymi i docelowymi.
Uwaga - REN może być użyte do zmiany nazwy folderu, ale symbole wieloznaczne nie są dozwolone ani w sourceMask ani targetMask podczas zmiany nazwy folderu. Jeśli sourceMask pasuje do co najmniej jednego pliku, wówczas nazwa pliku zostanie zmieniona, a foldery zostaną zignorowane. Jeśli sourceMask pasuje tylko do folderów, a nie do plików, generowany jest błąd składniowy, jeśli symbole wieloznaczne pojawiają się w źródle lub celu. Jeśli sourceMask nic nie pasuje, wówczas pojawia się błąd „nie znaleziono pliku”.
Ponadto podczas zmiany nazw plików symbole wieloznaczne są dozwolone tylko w części nazwy pliku sourceMask. Symbole wieloznaczne nie są dozwolone w ścieżce prowadzącej do nazwy pliku.
sourceMask
SourceMask działa jako filtr do określania, które nazwy plików mają zostać zmienione. Symbole wieloznaczne działają tutaj tak samo, jak w przypadku każdego innego polecenia filtrującego nazwy plików.
?
- Odpowiada dowolnemu znakowi 0 lub 1 oprócz .
tej wieloznacznej jest zachłanny - zawsze zużywa następny znak, jeśli nie jest nim. .
Jednak nie pasuje do niczego bez niepowodzenia, jeśli na końcu nazwy lub jeśli następny znak jest.
*
- Dopasowuje dowolne 0 lub więcej znaków, w tym .
(z jednym wyjątkiem poniżej). Ten symbol wieloznaczny nie jest zachłanny. Będzie pasować tak mało lub tyle, ile jest potrzebne, aby umożliwić dopasowanie kolejnych znaków.
Wszystkie znaki niebędące symbolami wieloznacznymi muszą pasować do siebie, z kilkoma wyjątkami wyjątków.
.
- Pasuje do siebie lub może pasować do końca nazwy (nic), jeśli nie ma już więcej znaków. (Uwaga - poprawna nazwa systemu Windows nie może kończyć się na .
)
{space}
- Pasuje do siebie lub może pasować do końca nazwy (nic), jeśli nie ma już więcej znaków. (Uwaga - poprawna nazwa systemu Windows nie może kończyć się na {space}
)
*.
na końcu - Dopasowuje dowolne 0 lub więcej znaków z wyjątkiem .
Terminacji .
może być dowolną kombinacją .
i {space}
tak długo, jak ostatni znak w masce to .
Jest to jedyny wyjątek, w którym *
po prostu nie pasuje do żadnego zestawu znaków.
Powyższe zasady nie są tak skomplikowane. Ale jest jeszcze jedna bardzo ważna zasada, która sprawia, że sytuacja jest myląca: maska SourceMask jest porównywana zarówno z długą, jak i krótką nazwą 8.3 (jeśli istnieje). Ta ostatnia reguła może sprawić, że interpretacja wyników będzie bardzo trudna, ponieważ nie zawsze jest oczywiste, kiedy maska dopasowuje się za pomocą krótkiej nazwy.
Można użyć RegEdit, aby wyłączyć generowanie krótkich nazw 8.3 na woluminach NTFS, w którym to momencie interpretacja wyników maski pliku jest znacznie prostsza. Wszelkie 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 reguły działają również w przypadku nazwy docelowej polecenia COPY
TargMask określa nową nazwę. Jest zawsze stosowane do pełnej długiej nazwy; TargMask nigdy nie jest stosowany do krótkiej nazwy 8.3, nawet jeśli sourceMask pasuje do krótkiej nazwy 8.3.
Obecność lub brak symboli wieloznacznych w masce źródłowej nie ma wpływu na sposób przetwarzania symboli wieloznacznych w masce docelowej.
W poniższej dyskusji - c
oznacza dowolny znak, który nie jest *
, ?
lub.
Maska target jest przetwarzana względem nazwy źródła ściśle od lewej do prawej bez śledzenia wstecznego.
c
- Przesuwa pozycję w obrębie nazwy źródłowej, o ile następny znak nie jest, .
i dołącza c
do nazwy docelowej. (Zastępuje znak, który był w źródle c
, ale nigdy nie zastępuje .
)
?
- Dopasowuje następny znak z długiej nazwy źródłowej i dołącza go do nazwy docelowej, dopóki następny znak nie jest. .
Jeśli następny znak jest .
lub jeśli na końcu nazwy źródłowej, żaden wynik nie jest dodawany do wyniku, a bieżący pozycja w nazwie źródła pozostaje niezmieniona.
*
na końcu celu - Maskuje wszystkie pozostałe postacie ze źródła do celu. Jeśli już na końcu źródła, nic nie robi.
*c
- Dopasowuje wszystkie znaki źródłowe od bieżącej pozycji do ostatniego wystąpienia c
(chciwe dopasowanie z rozróżnianiem wielkości liter) i dołącza dopasowany zestaw znaków do nazwy docelowej. Jeśli c
nie zostanie znaleziony, wówczas dołączane są wszystkie pozostałe znaki ze źródła, a następnie c
Jest to jedyna znana mi sytuacja, w której dopasowanie wzorca pliku Windows rozróżnia małe i wielkie litery.
*.
- Dopasowuje wszystkie znaki źródłowe od bieżącej pozycji do ostatniego wystąpienia .
(chciwe dopasowanie) i dołącza dopasowany zestaw znaków do nazwy docelowej. Jeśli .
nie zostanie znaleziony, wszystkie pozostałe znaki ze źródła zostaną dodane, a następnie.
*?
- Dołącza wszystkie pozostałe postacie ze źródła do celu. Jeśli jest już na końcu źródła, nic nie robi.
.
bez *
naprzeciwko - Advances pozycję w źródle poprzez pierwszym wystąpieniu o .
nie kopiowanie jakichkolwiek znaków, i dołącza .
do nazwy docelowej. Jeśli .
nie znaleziono go w źródle, następuje przejście do końca źródła i dopisanie .
do nazwy celu.
Po wyczerpaniu docelowej maski, wszelkie końcowe .
i {space}
są przycinane na końcu wynikowej nazwy docelowej, ponieważ nazwy plików systemu Windows nie mogą kończyć się na .
lub{space}
Kilka praktycznych przykładów
Zastąp znak na 1. i 3. pozycji przed dowolnym rozszerzeniem (dodaje 2 lub 3 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
Zmień (ostateczne) rozszerzenie każdego pliku
ren * *.txt
a -> a.txt
b.dat -> b.txt
c.x.y -> c.x.txt
Dołącz rozszerzenie do każdego pliku
ren * *?.bak
a -> a.bak
b.dat -> b.dat.bak
c.x.y -> c.x.y.bak
Usuń dodatkowe rozszerzenie po początkowym rozszerzeniu. Należy pamiętać, że ?
należy zachować odpowiednią wartość, 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 odfiltruj pliki o początkowej nazwie i / lub rozszerzeniu dłuższym niż 5 znaków, aby nie zostały obcięte. (Oczywiście można dodać dodatkowy ?
na każdym końcu 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 _
nazwisku i spróbuj zachować rozszerzenie. (Nie działa poprawnie, jeśli _
pojawia się 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)
Każda nazwa może być podzielona na komponenty, które są rozdzielane znakami. .
Można je dodawać lub usuwać tylko na końcu każdego komponentu. Znaków nie można usuwać ani dodawać na początku lub w środku komponentu, zachowując pozostałą część za pomocą symboli wieloznacznych. Zastępstwa są dozwolone w dowolnym miejscu.
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, wówczas maska 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
Przydatne dziwactwo / błąd? do usuwania prefiksów nazw
W tym poście o SuperUser opisano, jak można użyć zestawu ukośników ( /
), aby usunąć wiodące znaki z nazwy pliku. Jeden znak ukośnika jest wymagany do usunięcia każdego znaku. Potwierdziłem zachowanie na komputerze 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 podwójne cudzysłowy. Wszystkie poniższe formularze bez wymaganych cytatów kończą się 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
Nie /
można go użyć do usunięcia jakichkolwiek znaków na środku lub na końcu nazwy pliku. Może usuwać tylko wiodące (przedrostki) znaki.
Technicznie /
nie działa jak symbol wieloznaczny. Raczej wykonuje prostą zamianę znaków, ale następnie po zamianie komenda REN rozpoznaje, że /
nie jest poprawna w nazwie pliku, i usuwa z niej wiodące /
ukośniki. REN podaje błąd składniowy, jeśli wykryje /
w środku nazwy celu.
Możliwy błąd RENAME - pojedyncze polecenie może zmienić nazwę tego samego pliku dwa razy!
Począwszy od pustego folderu testowego:
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 pasuje do długiej nazwy pliku, a nazwa pliku zmienia się na oczekiwany wynik 223456789.123.x
. RENAME następnie szuka dalszych plików do przetworzenia i znajduje nowo nazwany plik za pomocą nowej krótkiej nazwy 223456~1.X
. Nazwa pliku jest następnie ponownie zmieniana, co daje końcowy wynik 223456789.123.xx
.
Jeśli wyłączę generowanie nazw 8.3, to RENAME daje oczekiwany wynik.
Nie w pełni opracowałem wszystkie warunki wyzwalające, które muszą istnieć, aby wywołać to dziwne zachowanie. Martwiłem się, że może być możliwe utworzenie niekończącej się rekurencyjnej RENAME, ale nigdy nie byłem w stanie jej wywołać.
Uważam, że wszystkie poniższe warunki muszą być prawdziwe, aby wywołać błąd. Każda skrzynka, którą widziałem, miała następujące warunki, ale nie wszystkie skrzynki, które spełniały następujące warunki, były błędne.
- Krótkie nazwy 8.3 muszą być włączone
- SourceMask musi pasować do oryginalnej długiej nazwy.
- Początkowa zmiana nazwy musi wygenerować krótką nazwę, która również pasuje do maski źródłowej
- Początkowa krótka nazwa musi zostać posortowana później niż oryginalna krótka nazwa (jeśli istnieje?)