Centrum skryptów - Systemy operacyjne

Jak zmienić plik znajdujący się w folderze i wszystkich jego podfolderach najwyższego poziomu?

Udostępnij na: Facebook

Skrypciarze odpowiadają na Wasze pytania

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.

Jak zmienić plik znajdujący się w folderze i wszystkich jego podfolderach najwyższego poziomu?

Cześć Skrypciarze! Potrzebuję pomocy. Mam jeden folder główny zawierający wiele podfolderów; wszystkie podfoldery są folderami najwyższego poziomu, np. C:\Scripts\Folder1 oraz C:\Scripts\Folder2. w każdym podfolderze znajduje się plik tekstowy o tej samej nazwie. Muszę otworzyć ten plik tekstowy w każdym podfolderze i zmienić w nim kilka znaków. Czy możecie mi w tym pomóc?

-- DJ

Cześć, DJ. To już wszystko: Zimowa Olimpiada Skrypciarska 2008 należy już do przeszłości. Wczoraj zamknęliśmy wszystkie konkurencje. Teraz pozostaje Wam tylko czekać na informacje dotyczące wygranych nagród (j.ang.), w tym laleczek dr Scripto oraz 50 egzemplarzy systemu operacyjnego Windows Vista Ultimate.

Uwaga. Czy ktoś, kto wziął udział w jakiejś konkurencji dosłownie w ostatniej chwili, ma takie same szanse na otrzymanie nagrody, jak ktoś, kto całe dwa tygodnie ciężko na nią pracował, tworząc skrypty w każdej konkurencji? Cóż, przyznaję, brzmi to trochę niedorzecznie. Ale widocznie tak musi być; w końcu w taki sposób przyznawane są roczne premie wydajnościowe w firmie Microsoft.

W każdym razie mam nadzieję, że podczas tegorocznej Olimpiady wszyscy się świetnie bawili; Skrypciarze bawili się przednio, jeżeli pominąć fakt, że prawie w ogóle nie spali. Już nie możemy doczekać się następnej olimpiady, mamy zamiar wymyślić na nią coś naprawdę specjalnego. Nie wybraliśmy jeszcze dokładnego terminu, ale 13 lutego 2009 r. to także piątek trzynastego. Ciężko byłoby nam przepuścić tak symboliczną datę rozpoczęcia olimpiady, jak piątek trzynastego. Możecie więc już wstępnie zaznaczyć tę datę w kalendarzu.

Koniec olimpiady oznacza dla Skrypciarzy powrót do normalnych zajęć. Prawdę mówiąc, nie pamiętam, na czym polegają moje normalne zajęcia; jak już mówiłem, w ciągu ostatnich kilku tygodni niewiele spałem. Przypominam sobie tylko, że miałem Wam przedstawić skrypt, który może zmodyfikować określony plik tekstowy znajdujący się w folderze oraz podfolderach najwyższego poziomu tego folderu. Mam nadzieję, że nic mi się nie pomieszało. W przeciwnym wypadku poniższy skrypt nikomu się nie przyda:

Const ForReading = 1

Const ForWriting = 2



strFileName = "Test.txt"

strParentFolder = "C:\Scripts\"



Set objFSO = CreateObject("Scripting.FileSystemObject")



strTextFile = strParentFolder & strFileName



Set objFile = objFSO.OpenTextFile(strTextFile, ForReading)

strContents = objFile.ReadAll

objFile.Close



strContents = Replace(strContents, "Contoso.com", "Fabrikam.com")



Set objFile = objFSO.OpenTextFile(strTextFile, ForWriting)

objFile.Write strContents

objFile.Close



Set objFolder = objFSO.GetFolder(strParentFolder)

Set colSubfolders = objFolder.Subfolders



For Each objSubfolder in colSubfolders

    strFolderName = objSubfolder.Path

    strTextFile = strFolderName & "\" & strFileName



    Set objFile = objFSO.OpenTextFile(strTextFile, ForReading)

    strContents = objFile.ReadAll

    objFile.Close



    strContents = Replace(strContents, "Contoso.com", "Fabrikam.com")

    Set objFile = objFSO.OpenTextFile(strTextFile, ForWriting)

    objFile.Write strContents

    objFile.Close

Next

Zobaczmy, jak ten skrypt działa.

Uwaga. Jak się pewnie domyślacie, przede mną następna długa noc; już jest dość późno, a ja mam jeszcze tyle rzeczy do zrobienia. Czy ja narzekam? Oczywiście, że tak. Ale nasza Redaktorka, która nie może iść do domu dopóki ja nie skończę tego artykułu, ma jeszcze gorzej. Trochę to pocieszające.

Innymi słowy ode mnie zależy, czy Redaktorka się dzisiaj wyśpi. Hmm … zanim przejdę do opisywania skryptu, chciałbym Wam tyle opowiedzieć ….

Zresztą nieważne, sam jestem na to zbyt zmęczony. Zaczną wiec od tego, że zaczynamy od zdefiniowania pary stałych, ForReading oraz ForWriting; wykorzystamy je podczas otwierania konkretnego pliku. Następnie przypisujemy wartości do dwóch zmiennych. Zmiennej strFileName przypisujemy nazwę pliku, który chcemy zmodyfikować, w naszym przypadku jest to Test.txt. Natomiast zmienna strParentFolder otrzymuje przypisaną nazwę folderu głównego. W naszym przykładowym skrypcie jest to C:\Scripts\.

Po ukończeniu czynności związanych z ustawianiem tworzymy wystąpienie obiektu Scripting.FileSystemObject; wykorzystamy ten wielofunkcyjny obiekt COM zarówno do odczytania z plików tekstowych, jak i do zapisu w nich oraz w celu pobrania kolekcji wszystkich podfolderów najwyższego poziomu znajdujących się w folderze C:\Scripts. Następnie tworzymy ścieżkę do pliku tekstowego w folderze głównym (C:\Scripts\Test.txt), łącząc nazwę folderu oraz nazwę pliku:

strTextFile = strParentFolder & strFileName

Do czego potrzebna jest nam ta ścieżka? To proste; za pomocą następnego wiersza kodu używamy metody OpenTextFile w celu otwarcia tego pliku tekstowego do odczytu:

Set objFile = objFSO.OpenTextFile(strTextFile, ForReading)

Od razu po otwarciu pliku używamy metody ReadAll w celu odczytania całej zawartości pliku i zachowujemy te informacje w zmiennej o nazwie strContents. Następnie wywołujemy metodę Close w celu zamknięcia pliku.

Jednak nie na długo; wrócimy do tego pliku za kilka sekund.

Nie wiemy, jakie dokładnie znaki DJ chce zastąpić, użyjemy więc prostego przykładu. Przypuśćmy, że każdy z tych plików zawiera listę domeny Contoso.com, która została ostatnio zmieniona na Fabrikam.com. Jak zastąpić wszystkie wystąpienia Contoso.com wystąpieniami Fabrikam.com? W taki oto sposób oczywiście:

strContents = Replace(strContents, "Contoso.com", "Fabrikam.com")

Używamy tutaj tylko metody Replace w celu przeszukania zmiennej strContents („wirtualnej” kopii pliku tekstowego) i zastąpienia wszystkich wystąpień Contoso.com ciągiem Fabrikam.com. Możecie wierzyć lub nie, ale to naprawdę jest takie proste.

Oczywiście to powoduje zmodyfikowanie wyłącznie wirtualnej kopii pliku; teraz musimy wprowadzić te zmiany w samym pliku tekstowym. W tym celu najpierw otwieramy ponownie plik Test.txt, tym razem do zapisu:

Set objFile = objFSO.OpenTextFile(strTextFile, ForReading)

Po wykonaniu tej czynności wywołujemy metodę Write w celu zastąpienia istniejącej zawartości pliku wartością zmiennej strContents:

objFile.Write strContents

Teraz wywołujemy metodę Close i na tym koniec.

Cóż, przynajmniej koniec pracy z plikiem w folderze głównym; teraz musimy zrobić coś z wersją pliku, która pojawia się w każdym podfolderze najwyższego poziomu. W tym celu używamy poniższych dwóch wierszy kodu po to, by połączyć się z folderem głównym (C:\Scripts) i pobieramy kolekcję wszystkich podfolderów najwyższego poziomu znajdujących się w tym folderze:

Set objFolder = objFSO.GetFolder(strParentFolder)

Set colSubfolders = objFolder.Subfolders

Teraz postępujemy w ten sam sposób, jak podczas zmiany kopii pliku Test.txt znajdującej się w folderze głównym. Na początek tworzymy ścieżkę pliku Test.txt w pierwszym podfolderze za pomocą poniższych dwóch wierszy kodu:

strFolderName = objSubfolder.Path

strTextFile = strFolderName & "\" & strFileName

Po utworzeniu tej ścieżki używamy obiektu FileSystemObject w celu otwarcia pliku i wczytania jego zawartości do pamięci. Wykonujemy czynność znajdź-i-zamień, a następnie wpisujemy zmodyfikowaną zawartość z powrotem do pliku. Potem kontynuujemy działanie pętli i powtarzamy proces dla następnego podfolderu w kolekcji.

Dziecinnie proste.

Po warunkiem, że dzieci też potrafią pisać skrypty administrowania systemem. Jak wiemy, niektóre dzieci potrafią.

I to już wszystko, DJ. Problem rozwiązany.

Zanim wreszcie pójdę spać, chciałbym bardzo podziękować wszystkim uczestnikom za udział w Zimowej Olimpiadzie Skrypciarskiej 2008; bardzo miło zaskoczyła nas liczba zainteresowanych w tym roku. (Dziękuję również za wsparcie osób zajmujących się językiem Perl.) Pamiętajcie, że przedłużyliśmy termin ponownego przesyłania zgłoszeń w aktualnych konkurencjach do czwartku, 6 marca 2008, 8:00 AM czasu Redmond. Innymi słowy, jeżeli otrzymaliście 0 w jakiejś konkurencji, nie musicie się martwić; do czwartku rano macie czas, żeby naprawić problem w swoim skrypcie i przesłać go ponownie. Przy założeniu, że nowy skrypt zadziała, otrzymacie punkty w danej konkurencji.

I nie zapomnijcie przysłać nam swoich komentarzy na temat Olimpiady. Powiedzcie nam, co Wam się podobało, a co nie i opowiedzcie o tym, co chcielibyście zobaczyć na przyszłorocznej Olimpiadzie w 2009 roku. Dotyczy to także pomysłów na nowe konkurencje, jeżeli macie jakiś pomysł, koniecznie nam o nim opowiedzcie.

 Do początku strony Do początku strony

Centrum skryptów - Systemy operacyjne