Centrum skryptów - Systemy operacyjne

Jak usunąć określone znaki z początku i końca nazw plików?

Udostępnij na: Facebook

Skrypciarze odpowiadają na Wasze pytania

Cześć Skrypciarze!

Witamy w rubryce TechNet, w której Skrypciarze z firmy Microsoft odpowiadają na częste pytania dotyczące używania skryptów w administracji systemu. Jeśli macie jakieś pytania z tej dziedziny, zachęcamy do wysłania e-maila na adres: scripter@microsoft.com. Nie możemy zagwarantować odpowiedzi na każde otrzymane pytanie, ale staramy się jak możemy.

CONTENT

Jak usunąć określone znaki z początku i końca nazw plików?

Cześć Skrypciarze! Pytanie

Cześć, Skrypciarze! Jak skrócić nazwy plików, usuwając powtarzający się w nich początek i koniec i pozostawiając ich unikatowe, środkowe części?

-- RE

Cześć Skrypciarze! Odpowiedź

Cześć, RE. Zanim odpowiem na, muszę wyjaśnić, że strajk anegdotowy trwa. Dlatego też i dzisiaj nie będzie żadnej anegdoty. Gorzej: nie będzie żadnych anegdot, dopóki Skrypciarska Redaktorka nie otrzyma tylu e-maili z protestami od czytelników, że ulegnie i spełni wszystkie nasze żądania. Jakie to były żądania, już nie pamiętam, ale na pewno pamiętają oburzeni czytelnicy.

Tak więc – patrz, Redaktorko, jak wszyscy przez ciebie cierpią – przejdźmy do dzieła. RE ma folder zawierający listę plików zbliżoną do poniższej:

8901 George.txt

File 1234 George.txt

File 2345 George.txt

File 3456 George.txt

File 4567 George.txt

File 5678 George.txt

File 6789 George.txt

File 7890.txt

Jak widać, większość nazw plików zaczyna się słowem File i kończy słowem George; niektóre zaczynają się na File, ale nie kończą na George, inne natomiast kończą się na George, ale nie zaczynają na File. Jednak wszystkie pliki mają unikatowy element w środku, np. w pliku File 1234 George.txt jest to 1234. RE chce zachować ten środkowy element, usuwając słowa File i George, co powinno dać taką listę:

8901.txt

1234.txt

2345.txt

3456.txt

4567.txt

5678.txt

6789.txt

7890.txt

Jak to zrobić? Ano tak, na przykład:

strComputer = "."



Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")



Set colFiles = objWMIService.ExecQuery _

    ("ASSOCIATORS OF {Win32_Directory.Name='C:\Test'} Where " _

        & "ResultClass = CIM_DataFile")



For Each objFile In colFiles

    strPath = objFile.Drive & objFile.Path

    strExtension = objFile.Extension

    strFileName = objFile.FileName



    If Left(strFileName, 5) = "File " Then

        intLength = Len(strFileName)

        strFileName = Right(strFileName, intLength - 5)

    End If



    If Right(strFileName, 7) = " George" Then

        intLength = Len(strFileName)

        strFileName = Left(strFileName, intLength - 7)

    End If



    strNewName = strPath & strFileName & "." & strExtension

    errResult = objFile.Rename(strNewName)

Next

Szczerze mówiąc, trafia do nas sporo pytań tego rodzaju, dotyczących usuwania fragmentów tekstu znajdujących się na początku albo końcu nazw plików. Dlatego też, a także ze względu na to, że za to nam właśnie płacą, przyjrzyjmy się temu skryptowi bliżej i spróbujmy się zorientować, co się w nim dzieje.

Skrypt rozpoczyna działanie od połączenia z usługą WMI na komputerze lokalnym. Czy możemy zmodyfikować skrypt tak, aby wykonywał to samo zadanie na zdalnym komputerze? Jasne, że tak. Wystarczy przypisać nazwę komputera zdalnego do zmiennej strComputer:

strComputer = "atl-fs-01"

Po połączeniu z usługą WMI używamy poniższego fragmentu kodu, by zwrócić kolekcję wszystkich plików (wystąpień klasy CIM_DataFile) znajdujących się w folderze C:\Test:

Set colFiles = objWMIService.ExecQuery _

    ("ASSOCIATORS OF {Win32_Directory.Name='C:\Test'} Where " _

        & "ResultClass = CIM_DataFile")

Po zwróceniu kolekcji możemy uruchomić pętlę For Each, która przejdzie przez wszystkie znajdujące się w niej pliki. Potem możemy przejść do rzeczy.

Przyznajemy, że istnieje kilka sposobów wykonania tego zadania. Zdecydowaliśmy się na podejście wymagające kilku dodatkowych wierszy kodu, ale bezpieczniejsze w użyciu. Co sprawia, że jest ono bezpieczniejsze? Otóż na przykład moglibyśmy użyć funkcji Replace i zastąpić wszystkie wystąpienia docelowych ciągów znaków File i George w ścieżkach plików. Dlaczego tego nie zrobimy? Załóżmy, że mamy plik zatytułowany File George Washington File George.txt. Wykonanie prostej operacji wyszukania i zastąpienia dałoby nam taki plik:

Washington.txt

Innymi słowy, usunęlibyśmy nie tylko początek i koniec. To z kolei mogłoby spowodować konflikty nazw, gdyby katalog zawierał jeszcze np. plik File Washington George.txt. Wyobraźmy sobie jeszcze, że folder, w którym znajdują się interesujące nas pliki nazywa się Documents From George. Usunięcie wszystkich wystąpień słowa George zadziałałoby też w stosunku do nazwy folderu, a to spowodowałoby najróżniejsze kłopoty. A kłopotów chcemy unikać, szczególnie teraz, kiedy zależy nam na poparciu społecznym w sporze z wszechpotężną, złowrogą Redaktorką.

Tak czy inaczej, w pętli uruchamiamy następujące trzy wiersze kodu:

strPath = objFile.Drive & objFile.Path

strExtension = objFile.Extension

strFileName = objFile.FileName

Pobieramy tu po prostu różne elementy ścieżki pliku. Jeśli mamy plik o nazwie C:\Test\File 1234 George.txt, naszym zmiennym przypisane zostaną następujące wartości:

Zmienna Wartość
strPath C:\Test|
strExtension txt
strFileName File 1234 George

Więcej informacji o właściwościach typu Drive i Path można znaleźć w przewodniku Microsoft Windows 2000 Scripting Guide (j.ang.).

Kolejnym krokiem jest określenie, czy nazwa pliku zaczyna się ciągiem znaków File oraz ewentualne usunięcie tego ciągu. Służy do tego następujący blok kodu:

If Left(strFileName, 5) = "File " Then

    intLength = Len(strFileName)

    strFileName = Right(strFileName, intLength - 5)

End If

Jak widać, używamy funkcji Left do określenia, czy pięć początkowych znaków w nazwie naszego pliku to File (zwróćmy uwagę na spację na końcu). Załóżmy, że tak. W takim razie używamy funkcji Len do określenia liczby znaków w ciągu (tzn. jego długości) i zachowujemy tę wartość w zmiennej intLength:

intLength = Len(strFileName)

Dochodzimy w ten sposób do poniższego wiersza kodu:

strFileName = Right(strFileName, intLength - 5)

Usuwamy tu słowo File z początku nazwy pliku. Używamy tu funkcji Right do pobrania znaków z końca ciągu i poruszamy się w kierunku. Ile znaków zamierzamy pobrać? Otóż wszystkie minus 5. Będziemy dzięki temu mieć całą nazwę pliku bez pierwszych pięciu znaków. Innymi słowy, jeśli nasz plik nazywał się File 1234 George, właściwość strFileName przyjmie następującą wartość:

1234 George

Co znaczy, że jesteśmy dokładnie w połowie drogi.

Następnie wykonujemy podobną procedurę, by sprawdzić, czy słowo George (ponownie należy pamiętać o spacji, tym razem przed samym słowem) pojawia się na końcu pliku. Jeśli tak, to usuwamy je. Służy do tego poniższy blok kodu:

If Right(strFileName, 7) = " George" Then

    intLength = Len(strFileName)

    strFileName = Left(strFileName, intLength - 7)

End If

Jaki będzie ostateczny wynik? Otóż właściwość strFileName będzie miała wartość składającą się tylko ze środkowej części pierwotnej nazwy:

1234

Świetnie się składa, bo właśnie o to nam chodziło. Pozostaje jednak pewien problem: używając WMI nie można zmienić nazwy pliku, o ile do metody Rename nie przekaże się kompletnej ścieżki. (Co oznacza, że sama nazwa 1234 nam wcale nie wystarcza.) Dlatego też w skrypcie mamy poniższy wiersz kodu, tworzący nową ścieżkę pliku i przechowujący tę wartość w zmiennej strNewName:

strNewName = strPath & strFileName & "." & strExtension

Nie ma tu nic szczególnie złożonego. Łączymy po prostu poniższe wartości:

  • C:\Test\
  • 1234
  • .
  • txt

Ich połączenie sprawi, że właściwość strNewName uzyska taką wartość:

C:\Test\1234.txt

I wiecie co? Macie rację! Wartość ta niepokojąco przypomina pełną ścieżkę pliku! Możemy teraz wywołać metodę Rename i zmienić nazwę:

errResult = objFile.Rename(strNewName)

Teraz możemy powrócić na początek pętli i powtórzyć ten proces dla kolejnego pliku w kolekcji. Po zakończeniu działania skryptu, folder C:\Test będzie zawierać następujący zestaw plików:

8901.txt

1234.txt

2345.txt

3456.txt

4567.txt

5678.txt

6789.txt

7890.txt

Zupełnie nieźle, no nie?

 Do początku strony Do początku strony

Centrum skryptów - Systemy operacyjne