Centrum skryptów - Systemy operacyjne

Jak wyszukać numery telefonów we wszystkich plikach tekstowych znajdujących się w folderze?

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.

Jak wyszukać numery telefonów we wszystkich plikach tekstowych znajdujących się w folderze?

Cześć Skrypciarze! Pytanie

Cześć, Skrypciarze! We wczorajszym artykule pokazaliście nam, jak wyszukać numery telefonów w pliku tekstowym; obiecaliście także, że dzisiaj pokażecie, jak zmodyfikować skrypt, aby przeszukał wszystkie pliki tekstowe znajdujące się w danym folderze. Pora się wywiązać z tej obietnicy.

-- SE

Cześć Skrypciarze! Odpowiedź

Cześć, SE. Danego słowa dotrzymamy. Skrypciarze zawsze dotrzymują danego słowa. Chyba się jeszcze nie zdarzyło, żeby było inaczej, Jeżeli ktoś ma nam coś do zarzucenia, to proszę bardzo. Tylko po kolei. Wiele rzeczy można nam zarzucić, ale nie to, że jak coś obiecujemy, to nie dotrzymujemy słowa.

Oczywiście, że pokażemy skrypt umożliwiający przeszukanie wszystkich plików tekstowych znajdujących się w folderze pod kątem numerów telefonów, ale najpierw chcieliśmy przeprosić wszystkich czytelników za tę nieprzespaną noc. Naprawdę nie wiem, jak mogliśmy zostawić naszych kochanych czytelników bez dokończenia tej fascynującej opowieści i skazać ich na tę koszmarną noc. Oto więc druga część naszej opowieści o skrypcie wyszukującym numery telefonów, tym razem w plikach tekstowych znajdujących się w danym folderze:

Const ForReading = 1



Set objFSO = CreateObject("Scripting.FileSystemObject")



strComputer = "."



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



Set colFileList = objWMIService.ExecQuery _

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

        & "ResultClass = CIM_DataFile")



For Each objFile In colFileList

    strName = objFile.FileName 

    strName = Replace(strName, "_", " ")

    Wscript.Echo strName



    Set objFile = objFSO.OpenTextFile(objFile.Name, ForReading)

    strSearchString = objFile.ReadAll

    objFile.Close



    Set objRegEx = CreateObject("VBScript.RegExp")



    objRegEx.Global = True   

    objRegEx.Pattern = "\d{3}-\d{3}-\d{4} \([a-zA-Z]*\)"



    Set colMatches = objRegEx.Execute(strSearchString)  



    If colMatches.Count > 0 Then

       For Each strMatch in colMatches   

           Wscript.Echo strMatch.Value 

       Next

    End If



    Wscript.Echo

Next

No właśnie, trochę przydługi ten skrypt, przynajmniej jak na rubrykę Cześć Skrypciarze! Jednak nie ma co rozpaczać, prawie wszystko zostało już omówione we wczorajszym artykule. Dlatego też ominiemy część dotyczącą stosowania tradycyjnych poleceń służących do wyszukiwania numerów telefonów i zamiast tego skoncentrujemy się na tym, żeby nasze wyszukiwanie odnosiło się do wszystkich plików znajdujących się w folderze.

Naszym pierwszym krokiem będzie (zaraz po zdefiniowaniu stałej ForReading i utworzeniu wystąpienia obiektu Scripting.FileSystemObject) podłączenie się do usługi WMI na lokalnym komputerze. I zanim ktoś zapyta – nie, nie można zastosować tego skryptu do przeszukania plików na zdalnym komputerze, a to dlatego, że obiekt FileSystemObject nie może funkcjonować zdalnie. Nie oznacza to jednak, że nie można przeszukać plików na zdalnym komputerze, a jedynie, że trzeba będzie dokonać jakichś dodatkowych modyfikacji, aby to zrobić. Więcej informacji na ten temat można znaleźć w archiwalnym artykule: Jak odczytać plik tekstowy na na zdalnym komputerze?

Po podłączeniu do usługi WMI stosujemy poniższy wiersz kodu w celu pobrania kolekcji wszystkich plików znajdujących się w folderze C:\Scripts:

Set colFileList = objWMIService.ExecQuery _

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

        & "ResultClass = CIM_DataFile")

Żarty na bok: teraz wystarczy tylko zastąpić ścieżkę C:\Scripts ścieżką dostępu do folderu, gdzie zlokalizowane są nasze pliki tekstowe. Na przykład, jeżeli nasze pliki tekstowe znajdują się w folderze D:\Employees, należy zastosować poniższy wiersz kodu:

Set colFileList = objWMIService.ExecQuery _

    ("ASSOCIATORS OF {Win32_Directory.Name='D:\Employees'} Where " _

        & "ResultClass = CIM_DataFile")

Rzeczywiście, te zapytania Associators Of nie wyglądają zbyt ciekawie. Ale nie są takie groźne, na jakie wyglądają.

Kiedy już mamy kolekcję plików z folderu, uruchamiamy pętlę For Each, która przejdzie przez wszystkie elementy w tej kolekcji (czyli przez wszystkie pliki z folderu C:\Scripts). Pierwszą rzeczą, którą zrobimy wewnątrz tej pętli będzie zastosowanie następującego wiersza kodu:

strName = objFile.FileName 

strName = Replace(strName, "_", " ")

Wscript.Echo strName

Jak zauważyliśmy wczoraj, (typowy Skrypciarz: zawsze żyje przeszłością) mamy serię plików o nazwach wyglądających tak:

Jonathan_Haas.txt

Ken_Myer.txt

Pilar_Ackerman.txt

Widzimy, że każdy plik ma nazwę odpowiadającą nazwisku pracownika, którego dane są w nim zachowane. Wczoraj przeszukiwaliśmy tylko jeden plik (Ken_Myer.txt); ponieważ ścieżka dostępu do tego pliku była wpisana do naszego skryptu z klawiatury, nietrudno było się domyślić, czyj numer telefonu chcieliśmy wyszukać. (Nie, szanowna Redaktorko, niestety; chodzi o Kena Meyera.) Dzisiaj jednakże będzie inaczej: pobieramy kupę innych numerów telefonów należących do wielu innych osób. Nie ma potrzeby wspominać, że chcemy mieć wgląd w to, do kogo należą poszczególne numery telefonów. Dzięki naszemu sposobowi nazywania plików możemy po prostu sprawdzać nazwę pliku, dokonując w niej pewnej modyfikacji. W naszym pierwszym wierszu kodu uzyskujemy wartość właściwości FileName (czyli nazwy pliku bez rozszerzenia pliku) i zachowujemy ją w zmiennej o nazwie strName:

strName = objFile.FileName

Dzięki temu zmienna strName będzie miała następującą wartość:

Jonathan_Haas

Już jest dobrze, ale my zdecydowaliśmy posunąć się trochę dalej i zastąpić znak podkreślenia pustą spacją. Może Was to zaskoczy, ale zastosujemy do tego funkcję Replace skryptu VBScript, która zastępuje podkreślnik (_) pustą spacją (“ “):

strName = Replace(strName, "_", " ")

Zgadnijcie, co widzimy na ekranie kiedy wywołamy echo nowej wartości zmiennej strName? Znowu pudło, szanowna Redaktorko, prawidłowa odpowiedź to:

Jonathan Haas
Uwaga. To chyba nie jest najłatwiejszy dzień dla naszej Redaktorki. Wydaje nam się, że może być w lekkim szoku, ponieważ piszący te słowa Skrypciarz robi to, co mówił, że zrobi i to bez żadnego zaganiania, przypominania, poganiania i gróźb. Ale przecież co obietnica, to obietnica.

Wywoławszy echo nazwy pracownika, możemy wyszukać numery telefonów w pierwszym pliku (Jonathan_Haas.txt). Od tego momentu, w zasadzie większość skryptu wygląda tak samo jak skrypt omówiony wczoraj. Z jednym wszakże wyjątkiem i to niemałym: kiedy wywołujemy metodę OpenTextFile (którą musimy wywołać w celu otwarcia o odczytania pliku), nie stosujemy ścieżki C:\Scripts\Ken_Myer.txt wpisanej z klawiatury. Zamiast tego, przekazujemy do metody wartość właściwości Name (która, tak się składa, jest taka sama jak ścieżka dostępu do pliku):

Set objFile = objFSO.OpenTextFile(objFile.Name, ForReading)

Teraz dokonujemy odczytu pliku, zachowujemy jego zawartość w zmiennej o nazwie strSearchString, a następnie stosujemy tradycyjne wyrażenie do przeszukania tej zawartości pod kątem numerów telefonów. Po wywołaniu echa wszystkich odnalezionych w pliku numerów stosujemy polecenie Wscript.Echo w celu wywołania echa pustego wiersza na ekran. Kiedy skończymy z Jonathanem Haas, kontynuujemy działanie pętli i powtarzamy proces dla następnego pliku z kolekcji. Kiedy skończymy z wszystkimi plikami, nasz ekran powinien wyglądać tak:

Jonathan Haas

425-555-4241 (office)

425-555-9977 (home)



Ken Myer

425-555-1212 (office)

425-555-5656 (cell)

425-555-3434 (home)



Pilar Ackerman

425-555-2134 (office)

425-555-6341 (cell)

425-555-8900 (home)

O to przecież nam chodziło. Chcecie wykonać podobne wyszukiwanie w odniesieniu do wszystkich plików znajdujących się w folderze? Żaden problem. Wystarczy postępować według wzoru. Należy wykorzystać usługę WMI do uzyskania kolekcji wszystkich plików, a następnie zastosować właściwość Name do pobrania ścieżki dla danego pliku (na przykład, jeżeli chcemy przekazać ścieżkę do innego obiektu, jak np. FileSystemObject). Często otrzymujemy pytania dotyczące odczytu/zapisu w odniesieniu do wszystkich plików znajdujących się w danym folderze. Teraz już wiadomo, jak!

Na tym się kończy nasz dwuczęściowy epizod o wyszukiwaniu numerów telefonów w plikach tekstowych. Będziemy się starać, żeby kilkuczęściowe serie już więcej się u nas nie pojawiły. Nie będzie to łatwe, co mamy teraz zrobić z pierwszymi 67 artykułami z planowanej na 300 części serii o deklarowaniu zmiennych? Ale nie martwcie się, jakoś sobie poradzimy.

Uwaga. Czy naprawdę mieliśmy zamiar napisać serię 300 artykułów o deklarowaniu zmiennych? Tak naprawdę to nie. Ale chcieliśmy napisać pierwszych 5 albo 6 części, a potem powtarzać je do oporu. Tak sobie oszacowaliśmy, że po przeczytaniu 5 następujących po sobie artykułów o zmiennych odpadliby już wszyscy czytelnicy (i redaktorzy), więc nikt by nie zauważył, że cokolwiek powtarzamy.
 Do początku strony Do początku strony

Centrum skryptów - Systemy operacyjne