Centrum skryptów - Systemy operacyjne

Jak zlokalizować wartość w pliku tekstowym, a następnie przetworzyć linię tekstu, w której została znaleziona ta wartość?

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 zlokalizować wartość w pliku tekstowym, a następnie przetworzyć linię tekstu, w której została znaleziona ta wartość?

Cześć Skrypciarze! Pytanie

Cześć Skrypciarze! Jak otworzyć plik CSV, zlokalizować wartość w kolumnie 1, a następnie przechować wartość z kolumny 2 w zmiennej?

-- THvdH

Cześć Skrypciarze! Odpowiedź

Hej, HvdH. Chcąc być wobec Ciebie uczciwym musimy powiedzieć, że nie jest łatwo Skrytpującemu Gościowi, który jest autorem tej rubryki, skupić się dzisiaj na pracy. W końcu jutro jest jeden z największych i najlepszych weekendów w Stanach: spotkanie Terducken Bowl.

Święto Dziękczynienia? Oczywiście, jutro w USA jest również Święto Dziękczynienia... tak nam się przynajmniej wydaje. Prawdę mówiąc trochę żałujemy Święta Dziękczynienia: to wstyd, że przypada tego samego dnia co spotkanie Terducken Bowl. Lecz właśnie od tego są przerwy świąteczne, prawda?

Na wypadek gdyby ktoś nie wiedział co to takiego Terducken Bowl, to wyjaśniamy, że jest to coroczne spotkanie futbolowe, rozgrywane pomiędzy dwoma drużynami: Skrypciarzem, który jest autorem tej rubryki oraz jego Skrytpującym bratankiem (Jordanem), a Skryptującym Synem i drugim bratankiem (Blake'iem). Powiedzenie, że tegoroczny mecz jest najważniejszym wydarzeniem w historii wszechświata byłoby niedomówieniem. Skrypciarz, który napisał tę rubrykę (oraz jego waleczny bratanek Jordan) wygrali dwa pierwsze spotkania Terducken Bowls. Stało się to głównie za przyczyną tego, że Skrypciarz będący autorem tej rubryki był większy i szybszy niż Skrytpujące Dzieciaki. Jednakże w trzecim roku Skrypciarz z jakiegoś powodu zmalał i stał się najmniejszy i najwolniejszy ze wszystkich graczy. W rezultacie pomimo że każdy mecz w latach od 3 do 5 był zaciętą walką, Dylan, Skryptujący Syn oraz jego waleczny pomocnik wygrali wszystkie trzy spotkania.

Aż wreszcie nadszedł Terducken Bowl roku 2005. W tym meczu Skrypciarz oraz Jordan oszołomili publiczność (i - co jest dość interesujące - rzeczywiście była publiczność, składająca się z dzieciaków z sąsiedztwa, którzy przyszli popatrzeć na mecz) wskutek objęcia prowadzenia 21:0, a następnie grania sobie na luzie. W ten sposób każda z drużyn wygrała dotychczas trzykrotnie, przez co tegoroczny mecz stał się szczególnie ważny.

Uwaga. Interesuje Cię co zdobywa zwycięzca Terducken Bowl? Cóż, w rzeczywistości nic. Teoretycznie ma on możliwość przechwalania się przez cały rok, lecz od czasu kiedy kończymy bieganie w kółko po boisku, każdy jest zazwyczaj zbyt zmęczony i pozbawiony tchu, że nie ma już siły przechwalać się. Lecz przecież wiesz jak to jest: nie jest ważne czy coś zdobędziesz, ważne jest tylko to, czy wygrasz. Zwłaszcza wówczas, gdy Twój syn gra w drużynie przeciwnej.

W każdym razie Skrypciarz, który napisał tę rubrykę jest dziś nieco zaabsorbowany, ponieważ planuje strategię na jutrzejszy mecz (oczywiście na ogół strategia ta składa się z powiedzenia: "Ok, Jordan, biegnij tak daleko jak możesz, a ja spróbuję zrobić resztę"). Jednakże w przededniu weekendu Skrypciarz, który jest autorem tej rubryki zgodził się zrobić sobie krótką przerwę i pokazać Ci jak napisać skrypt, który otwiera plik CSV, znajduje wartość w jego pierwszej kolumnie, a następnie przechowuje w zmiennej wartość z kolumny drugiej.

To jest właśnie ten skrypt:

Const ForReading = 1



Set objFSo = CreateObject("Scripting.FileSystemObject")

Set objFile = objFSO.OpenTextFile("C:\Scripts\Test.txt")



Do Until objFile.AtEndOfStream

    strText = objFile.ReadLine

    If InStr(strText, "HE123-ASD-FRE-R4") Then

        arrText = Split(strText, ",")

        strVariable = arrText(1)

        Exit Do

    End If

Loop



objFile.Close



Wscript.Echo strVariable

Na podstawie Twojego emaila HvdH można wywnioskować, że Twój plik tekstowy składa się z nazw komputerów, po których występują ich adresy IP:

HE123-ASD-FRE-R01,192.168.1.5

HE123-ASD-FRE-R02,192.168.1.6

HE123-ASD-FRE-R03,192.168.1.33

HE123-ASD-FRE-R04,192.168.1.9

HE123-ASD-FRE-R05,192.168.1.44

Nasze zadanie – a raczej zadanie naszego skryptu – polega na zlokalizowaniu określonego komputera (w tym przypadku komputera o nazwie HE123-ASD-FRE-R04) oraz zwróceniu jego adresu IP: 192.168.1.9. Zobaczmy, czy zaproponowane przez nas rozwiązanie rzeczywiście to robi.

Jak widzisz zaczynamy od zdefiniowania stałej o nazwie ForReading i ustawieniu jej wartości na 1; użyjemy tej stałej podczas otwierania naszego pliku tekstowego. Po zdefiniowaniu stałej tworzymy obiekt Scripting.FileSystemObject, a następnie używamy jego metody OpenTextFile do otwarcia pliku C:\Scripts\Test.txt. Robimy to w poniższym fragmencie kodu:

Set objFSo = CreateObject("Scripting.FileSystemObject")

Set objFile = objFSO.OpenTextFile("C:\Scripts\Test.txt")

W następnym kroku tworzymy pętlę Do Until, w której linia po linii czytamy zawartość pliku, do momentu aż wszystkie linie zostaną odczytane. (Skąd wiemy kiedy to się stanie? Otóż wówczas, gdy właściwość AtEndOfStream przyjmie wartość True). Co prawda sprawdzanie pliku linia po linii to swego rodzaju metoda pełnego przeglądu (brute force); prawdopodobnie istnieją bardziej eleganckie sposoby osiągnięcia tego samego rezultatu. Dlaczego zatem zdecydowaliśmy się na zastosowanie takiej brutalnej metody? Stało się tak z dwóch powodów. Po pierwsze, w naszym mniemaniu podejście to jest dużo prostsze niż, powiedzmy, próba napisania wyrażenia regularnego, które wyszperałoby szukaną wartość. Po drugie, jeśli chodzi o czytanie plików tekstowych, to obiekt FileSystemObject jest naprawdę bardzo szybki: nawet jeśli Twój plik będzie zawierał tysiące nazw komputerów, FileSystemObject może go przetworzyć w kilka sekund. Z tych powodów zastosowanie metody pełnego przeglądu nie powoduje zauważalnego spadku wydajności. Mając wybór pomiędzy metodą łatwą i szybką a nieco szybszą i dużo bardziej skomplikowaną, zawsze wybierzemy tę pierwszą.

Wewnątrz pętli Do używamy metody ReadLine do odczytania pierwszej linii z pliku tekstowego i przechowania tej wartości w zmiennej o nazwie strText. Następnie korzystamy z funkcji InStr oraz poniższej linii kodu w celu określenia czy pobrana nazwa komputera jest tą, o którą nam chodzi:

If InStr(strText, "HE123-ASD-FRE-R4") Then

Jeśli funkcja InStr zwróci wartość 0, to będzie oznaczało, że żądana nazwa komputera nie wystąpiła nigdzie w pobranej linii tekstu. Dlatego po prostu wykonujemy kolejny obieg pętli i powtarzamy ten proces, ale tym razem już z kolejną linią z pliku tekstowego.

Ach, lecz przypuśćmy, że funkcja InStr zwróci coś innego niż 0. (Z technicznego punktu widzenia funkcja InStr zwraca początkową pozycję szukanego łańcucha znaków, o ile oczywiście łańcuch ten zostanie znaleziony). W tym przypadku wykonujemy poniższy fragment kodu:

arrText = Split(strText, ",")

strVariable = arrText(1)

W pierwszej linii używamy funkcji Split w celu podzielenia linii tekstu i zapisania poszczególnych jej fragmentów w tablicy o nazwie arrText. Ponieważ jako znaku rozdzielającego poszczególne kolumny w pliku CVS używamy przecinka, nasza tablica będzie docelowo składała się z dwóch elementów:

  • HE123-ASD-FRE-R04
  • 192.168.1.9

Oczywiście my jesteśmy zainteresowani drugim z tych elementów, tj. adresem IP. Jak już wiesz w języku VBScript każdemu elementowi tablicy automatycznie przyporządkowywany jest indeks: pierwszy element otrzymuje indeks równy 0, drugi element dostaje indeks równy 1 i tak dalej. Ponieważ nas interesuje drugi element (który posiada indeks 1), pobieramy go przy pomocy poniższej linii kodu oraz zapisujemy w zmiennej o nazwie strVariable:

strVariable = arrText(1)

W tym momencie zrobiliśmy to co do nas należało: zlokalizowaliśmy komputer docelowy, pobraliśmy jego adres IP oraz przechowaliśmy ten adres w zmiennej o nazwie strVariable. A zatem można jasno stwierdzić, że teraz nie musimy już odczytywać dalszej części pliku: znaleźliśmy już to, czego szukaliśmy. W związku z tym wywołujemy instrukcję Exit Do, umożliwiającą przerwanie pętli. Teraz, gdy już jesteśmy poza pętlą używamy metody Close do zamknięcia pliku, po czym wyświetlany na ekranie zawartość zmiennej strVariable:

192.168.1.9

I to jest już naprawdę wszystko. No i jesteśmy gotowi do tego, by wrócić do rzeczywistego zadania: jutrzejszego meczu Terducken Bowl.

Uwaga. Gdybyś zastanawiał się od czego pochodzi nazwa Terducken Bowl wyjaśniamy, iż wzięła się ona od słówka "terducken", pewnego mitycznego dania podawanego podczas Święta Dziękczynienia, które składało się z kurczaka będącego farszem dla kaczki, która z kolei wypełniała indyka i to wszystko było pieczone. Prawdę mówiąc nie znamy nikogo, kto rzeczywiście jadł danie terducken, lecz Skrytpujące Dzieciaki na tyle polubiły tę nazwę, że ochrzciły nią nasz mecz futbolowy Terducken Bowl.

Nawiasem mówiąc jest to ostatnia rubryka z cyklu Cześć Skrypciarze! aż do poniedziałku 27 listopada. To dlatego, że my pracownicy Microsoftu mamy następne cztery dni wolne z powodu Terducken Bowl. A tak, oznacza to również, że jeszcze nieprędko rezultat tego meczu zostanie opublikowany. De facto w zależności od tego kto wygra, może upłynąć dużo czasu, zanim świat pozna wynik meczu.

Uwaga. W czeczywistości Skrypciarz, który jest autorem tej rubryki jest pewny zwycięstwa. Tego roku zamierza on powiedzieć Jordanowi, aby biegł tak daleko jako może, a on spróbuje zrobić resztę. Dylan oraz Blake na pewno nie będą spodziewać się takiej strategii.
 Do początku strony Do początku strony

Centrum skryptów - Systemy operacyjne