Centrum skryptów - Systemy operacyjne

Jak mogę pobrać dane znajdujące się pomiędzy dwoma znanymi wartościami w pliku tekstowym?

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 mogę pobrać dane znajdujące się pomiędzy dwoma znanymi wartościami w pliku tekstowym?

Hey, Scripting Guy! Question

Cześć Skrypciarze! Jak z pliku tekstowego pobrać dane znajdujące się pomiędzy łańcuchem HOSTNAME= a spacją?

-- B

Cześć Skrypciarze! Odpowiedź

Hej, B. Musicie nam wybaczyć, jeśli będziemy dziś troszkę powolni; ciągle się jeszcze nie możemy pozbierać po całej tej zabawie podczas Tygodnia Windows PowerShell. A co jeśli przeoczyliście Tydzień Windows PowerShell? No to macie przechlapane. Teraz już nigdy nie uda wam się poznać tajników Windows PowerShell, stracicie pracę, wasz pies was pogryzie, a żona spakuje się i opuści.

OK, może więc jest przynajmniej jedna korzyść z opuszczenia Tygodnia Windows PowerShell - wiecie co mam na myśli.

Jeszcze sekundka, B...

Przepraszamy, najwyraźniej Skryptujący Redaktor znalazł literówkę w pierwszym akapicie dzisiejszej rubryki. Zamiast "No to macie przechlapane." powinno tam znaleźć się takie oto zdanie: "Nic się nie stało. W końcu wszystkie zasoby Tygodnia Windows Powershell - w tym łącza do emisji na żądanie, dzienniki pytań i odpowiedzi i inne powiązane dobra - są dostępne na witrynie Tygodnia WindowsPowerShell.” Tak więc nie mieliście jednak mimo wszystko pecha.

A tak, to oznacza, że musicie zachować pracę i żonę, przynajmniej na razie. Z drugiej strony, pies was zapewne nie pogryzie. I wciąż jeszcze możecie dowiedzieć się wszystkiego o Tygodniu Windows PowerShell.

Oczywiście, jedną z rzeczy, których nie znajdziecie na witrynie Tygodnia Windows PowerShell jest skrypt zwracający tekst znajdujący się pomiędzy łańcuchem HOSTNAME= i spacją w pliku tekstowym. Ale nie rozpaczajcie. Na szczęście, przez przypadek mamy tu skrypt, który potrafi wyciągnąć tego rodzaju informację ze zmiennej łańcuchowej. Pokażemy wam, jak działa taki ogólny skrypt, a potem przerobimy go trochę, żeby mógł wyciągnąć te same dane z pliku tekstowego.

Oto ten skrypt:

strSearchString = "ABCDEFGHIJK, NDPSGW PORT=LPR HOSTNAME=R2333_HP_1100 ABCDEFGHIJK"



intStart = InStr(strSearchString, "HOSTNAME=") intStart = intStart + 9



strText = Mid(strSearchString, intStart, 250)



For i = 1 to Len(strText) If Mid(strText, i, 1) = " " Then Exit For Else strData = _ 

strData & Mid(strText, i, 1) End If Next



Wscript.Echo strData

Jak wspomiał w emailu B, jego plik tekstowy zawiera wiersze, które wyglądają mniej więcej tak:

ABCDEFGHIJK, NDPSGW PORT=LPR HOSTNAME=R2333_HP_1100 ABCDEFGHIJK

Musimy znaleźć w nich łańcuch HOSTNAME=. Po znalezieniu łańcucha chcemy pobrać całość tekstu znajdującego się po znaku równości, przynajmniej do napotkania spacji. W tym przykładzie oznacza to pobranie tekstu R2333_HP_1100. Zobaczmy, czy wykombinujemy jak to zrobić.

Uwaga: Zanim przejdziemy dalej, powinniśmy zwrócić uwagę, że istnieje kilka sposobów rozwiązania tego problemu. Przykładowo moglibyśmy do zlokalizowania poszukiwanej wartości użyć wyrażeń regularnych. Podejście, które wybraliśmy nie jest może najbardziej wyrafinowane, ale pomyśleliśmy, że to sposób najłatwiejszy i najprostszy. Ponadto wydaje nam się, że typowemu administratorowi będzie najbardziej odpowiadał taki właśnie skrypt. Jak zwykle, mniej przejmujemy się elegancją rozwiązania, niż znalezieniem rozwiązania i wykonaniem pracy.

Jak widzicie, zaczynamy od przypisania przykładowego wiersza tekstu do zmiennej o nazwie strSearchString. Następnie za pomocą funkcji InStr w kolejnym wierszu kodu określamy pozycję początku łańcucha HOSTNAME=:

intStart = InStr(strSearchString, "HOSTNAME=")

W tym przypadku funkcja InStr zwróci wartość 30. Dlaczego? Ponieważ łańcuch HOSTNAME= zaczyna się od 30 znaku łańcucha strSearchString (policzcie znaki to sami zobaczycie). Jasne, znajomość pozycji początku łańcucha HOSTNAME= przyda się, ale to jeszcze nie rozwiązuje naszego problemu: musimy wiedzieć, gdzie ten łańcuch się kończy. Dlaczego? Ponieważ od tego miejsca zaczniemy pobieranie danych. Na szczęście łatwo pokonamy tę przeszkodę: HOSTNAME= ma długość 9 znaków, co oznacza, że wystarczy dodać do zmiennej intStart wartość 9 i już mamy dokładne miejsce, gdzie zaczynają się dane docelowe. To właśnie robimy w tym wierszu kodu:

intStart = intStart + 9

Jak powiedzieliśmy, teraz już wiemy gdzie zaczynają się nasze dane: w tym przypadku od znaku 39 (30 + 9). (Może się wydawać, że pomyliliśmy się w liczeniu o 1. Ale, powtórzymy - policzcie liczbę znaków sami i zobaczycie, że wszystko jest OK.) Między innymi, oznacza to, że możemy pominąć pierwsze 39 znaków łańcucha - nie ma w nich nic, co by nas interesowało. Pamiętając o tym, za pomocą poniższego wiersza kodu stworzymy nowy łańcuch (przechowywany w zmiennej strText) rozpoczynający się od znaku 39 i zawierający następne 250 znaków:

strText = Mid(strSearchString, intStart, 250)

Uwaga. Dlaczego 250? Właściwie to liczba wzięta z głowy: chcieliśmy być pewni, że pobierzemy wszystkie pozostałe znaki łańcucha. I tak, mogliśmy obliczyć długość łańcucha i określić dokładnie liczbę znaków do pobrania, ale przyjmujemy, że nie będziecie mieć wierszy dłuższych niż 250 znaków. Jeśli macie, to musicie odpowiednio zmienić ten wiersz.

I nie ma co się martwić: jeśli łańcuch zawiera mniej niż 250 znaków, nie spowoduje to żadnego błędu w tym wierszu kodu. VBScript pobierze tyle znaków ile istnieje i wystarczy.

Teraz tworzymy pętlę For Next indeksowaną od 1 (co reprezentuje pierwszy znak w zmiennej strText), która zakończy pracę po osiągnięciu końca łańcucha (który określimy za pomocą funkcji Len):

For i = 1 to Len(strText)

Co będziemy robić wewnątrz pętli? Na początek, sprawdzimy pierwszy znak i zobaczymy, czy trafiliśmy na spację (pamiętacie - gdy znajdziemy spację, znaczy to, że dotarliśmy do końca naszych danych). Jeśli pierwszy znak jest spacją wywołujemy polecenie Exit For i opuszczamy pętlę. Jeśli zaś nie jest spacją, korzystamy z funkcji Mid i poniższego kodu, by dodać znak do zmiennej o nazwie strData (w argumentach przekazywanych funkcji Mid i oznacza literę w łańcuchu, a 1 informuje, że ma zostać pobrany tylko ten jeden znak):

strData = strData & Mid(strText, i, 1)

Co to oznacza? W przykładzie, pierwszy znak to litera R. Litera R nie jest spacją, więc dodajemy wartość R do zmiennej strData. Przechodzimy znowu na początek pętli i sprawdzamy drugi znak łańcucha: 2. Znowu nie jest to spacja, więc dodajemy do strData kolejny znak. Zmienna strData ma teraz wartość R2. Znowu przechodzimy na początek pętli i sprawdzamy trzeci znak łańcucha - i tak dalej, aż zabraknie nam znaków do sprawdzania albo natrafimy na spację.

Po opuszczeniu pętli wypisujemy wartość zmiennej strData, która przy odrobinie szczęścia powinna wyglądać tak:

R2333_HP_1100

No i gotowe.

Teraz: jak zrobić to samo z plikiem tekstowym? Ano tak, oczywiście:

Const ForReading = 1



Set objFSO = CreateObject("Scripting.FileSystemObject") Set objFile = _  

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



Do Until objFile.AtEndOfStream strData = "" strSearchString = objFile.ReadLine



    intStart = InStr(strSearchString, "HOSTNAME=")



    If intStart <> 0 Then intStart = intStart + 9 strText = Mid(strSearchString, intStart, 250)



        For i = 1 to Len(strText) If Mid(strText, i, 1) = " " Then Exit For Else strData = _ 

        strData & Mid(strText, i, 1) End If Next End If Wscript.Echo strData Loop

Nie będziemy się zagłębiać w szczegóły czytania plików tekstowych; jest już dość rubryk Cześć Skrypciarze!, które mogą pomóc je zrozumieć. Ale teraz, znając podstawy wyszukiwania informacji, zrozumienie zasady działania tej wersji skryptu nie powinno stanowić dla was problemu.

Mamy nadzieję, że pomogliśmy, B. I raz jeszcze powtórzymy: jeśli ominął was Tydzień Windows PowerShell nie martwcie się: wciąż możecie rozkoszować się każdą jego minutą. Czy prawdą jest, że w wyemitowanym piątego dnia materiale Peter Constantini zaśpiewał nie jedną ale dwie piosenki o Windows PowerShell? Ujmijmy to tak: jeśli usłyszycie jakąś historię o Peterze, to nie ważne jakby była szalona, powinniście założyć, że to prawda.

Ale dlaczego nie sprawdzić materiałów z piątego dnia i nie przekonać się samemu?

 Do początku strony Do początku strony

Centrum skryptów - Systemy operacyjne