Centrum skryptów - Systemy operacyjne

Jak przeprowadzić analizę pliku zawierającego wartości oddzielone przecinkami?

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 przeprowadzić analizę pliku zawierającego wartości oddzielone przecinkami?

Cześć Skrypciarze! Pytanie

Cześć, Skrypciarze! Mam plik tekstowy składający się z pojedynczych pól oddzielonych przecinkami. Muszę sprawdzić drugie pole w każdym wierszu i, jeżeli zawiera ono słowo Everyone, wpisać wartość znajdującą się w szóstym polu do drugiego pliku tekstowego. Jak to zrobić?

-- RP

Cześć Skrypciarze! Pytanie

Cześć, RP. Zastanawiacie się może czasem, jak wygląda życie innych ludzi gdzieś na drugiej półkuli, tysiące kilometrów od was, w zupełnie innym klimacie? Ja robię to często i czasem wydaje mi się, że moje życie byłoby o wiele ciekawsze, gdybym mieszkał np. w Polsce, tam się dzieje o wiele więcej, niż u nas. Z kolei wiem, że wiele osób myśli, że życie w Seattle jest strasznie ekscytujące i dałoby sporo, żeby móc tu zamieszkać. Znacie to powiedzenie, że wszędzie dobrze, gdzie nas nie ma, prawda? Jest też drugie, a mianowicie: wszędzie dobrze, ale w domu najlepiej. Tego mam zamiar się trzymać i będę to sobie powtarzał za każdym razem, gdy zapragnę jakiejś odmiany. Chyba właśnie nadszedł ten czas, bo nie mogę się skupić i naprawdę bardzo chciałbym być w jakimś innym miejscu, w którym nie ma wieżowców, skryptów ani niczego, za czym mógłbym szybko zatęsknić.

Nie będę jednak przedłużał, im szybciej napiszę skrypt, tym szybciej będę mógł zacząć rozmyślać o tym, gdzie mógłbym właśnie spędzać czas.

Oto skrypt:

Const ForReading = 1



Set objFSO = CreateObject("Scripting.FileSystemObject")

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



Do Until objFile.AtEndOfStream

    strLine = objFile.ReadLine

    arrFields = Split(strLine, ",")



    If InStr(arrFields(1), "Everyone") Then

        strContents = strContents & arrFields(5) & vbCrlf

    End If

Loop



objFile.Close



Set objFile = objFSO.CreateTextFile("C:\Scripts\Everyone.txt")

objFile.Write strContents



objFile.Close

Zanim zabierzemy się za wyjaśnienie jego działania, zobaczmy, jak wygląda nasz plik tekstowy (C:\Scripts\Test.txt):

MBPGPS1PRN-001\,Administrators,LOCALGROUP,S-1-5-32-544,PRINTSHARE,\\MBPGPS1PRN-001\mbbetsb01,OWNER,,

MBPGPS1PRN-001,Everyone,GLOBALGROUP,S-1-1-0,PRINTSHARE,\\MBPGPS1PRN-001\mbbetsb01,(+PrR),,

MBPGPS1PRN-001,Everyone,GLOBALGROUP,S-1-1-0,PRINTSHARE,\\MBPGPS1PRN-002\mbbetsb01,(+PrR),,

MBPGPS1PRN-001,Administrators,GLOBALGROUP,S-1-1-0,PRINTSHARE,\\MBPGPS1PRN-001\mbbetsb01,(+PrR),,

MBPGPS2PRN-001,Everyone,GLOBALGROUP,S-1-1-0,PRINTSHARE,\\MBPGPS2PRN-001\mbbet02,(+PrR),,

Jak zauważyliśmy, każdy wiersz w tym pliku składa się z kilku różnych pól. Musimy sprawdzić drugi element w każdym wierszu (np. Administrators) i określić, czy ta wartość zawiera słowo Everyone. (Nie, nie zawiera, a przynajmniej nie w wierszu pierwszym.) Jeżeli drugi element zawiera słowo Everyone (jak to jest w przypadku wiersza 2 w pliku), będziemy musieli wydobyć szósty parametr (ścieżkę drukarki podobną do MBPGPS1PRN-001\mbbetsb01) i wpisać tę informację do drugiego pliku.

Teraz zajmijmy się skryptem i jego działaniem.

Jak widać, zaczynamy od zdefiniowania stałej o nazwie ForReading i przypisujemy jej wartość 1; wykorzystamy tę stałą podczas otwierania pliku Test.txt. Tak się składa, że następnie tworzymy wystąpienie obiektu Scripting.FileSystemObject i stosujemy metodę OpenTextFile w celu otwarcia pliku Test.txt do odczytu. Do tego posłużą nam poniższe dwa wiersze kodu:

Set objFSO = CreateObject("Scripting.FileSystemObject")

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

Zanim będziemy mogli odczytać i przeanalizować plik wiersz po wierszu, musimy ustawić pętlę Do Until, która będzie działać dopóki właściwość AtEndOfStream pliku nie uzyska wartości True. (Czyli po prostu dopóki nie dotrze do końca pliku.) Wewnątrz tej pętli najpierw stosujemy metodę ReadLine w celu odczytanie pierwszego wiersza w pliku i zachowania jej w zmiennej o nazwie strLine:

strLine = objFile.ReadLine

Teraz przechodzimy do następującego wiersza kodu:

arrFields = Split(strLine, ",")

Używamy funkcji Split, aby zamienić wartość ciągu strLine na tablicę; mówiąc bardziej konkretnie, funkcja Split ma utworzyć nowy element dla tablicy arrFields za każdym razem, gdy napotka przecinek. Dlaczego to robimy? Żeby otrzymać tablicę zawierającą następujące elementy:

  • MBPGPS1PRN-001\
  • Administrators
  • LOCALGROUP
  • S-1-5-32-544
  • PRINTSHARE
  • \\MBPGPS1PRN-001\mbbetsb01
  • OWNER

Czy to jest warte tego całego zachodu? Oczywiście, że tak; w końcu każdy element w tablicy odpowiada pojedynczym polom w naszym wierszu tekstu. Jak już zauważyliśmy, musimy sprawdzić, czy drugie pole w tym wierszu tekstu zawiera słowo Everyone. Można to zrobić w bardzo prosty sposób:

If InStr(arrFields(1), "Everyone") Then

Używamy teraz funkcji InStr, żeby określić, czy słowo Everyone znajduje się w drugim polu naszego wiersza tekstu. Lub, dokładniej mówiąc, sprawdzamy, czy słowo Everyone znajduje się w drugim elemencie naszej tablicy. Nie ma się co martwić, naprawdę sprawdzamy drugi element w tablicy, pomimo składni arrFields(1). W języku VBScript, tablice są „0-indeksowe.” Oznacza to, że pierwszy element tablicy ma przypisany numer indeksu 0, podczas gdy drugi element tablicy (ten, który nas interesuje) ma przypisany numer 1. Stąd wartość 1 w tablicy arrFields(1). Gdybyśmy chcieli sprawdzić trzeci element tablicy, zastosowalibyśmy składnię arrFields(2).

I tak dalej.

Jeżeli nie znajdziemy docelowego słowa w tablicy arrFields(1), uruchamiamy pętlę i powtarzamy proces dla następnego wiersza w pliku tekstowym. Jeżeli znajdziemy docelowe słowo, wykonujemy następujący wiersz kodu:

strContents = strContents & arrFields(5) & vbCrlf

Jedyne, co robimy, to przypisujemy wartość do zmiennej o nazwie strContents, wartość składającą się z istniejącej wartości zmiennej plus wartość szóstego elementu w tablicy plus znak powrotu karetki (vbCrLf). Określiliśmy 5 jako numer indeksu z bardzo konkretnego powodu: szósty element tablicy zawsze będzie miał numer indeksu 5.

Po odczytaniu i przeanalizowaniu każdego wiersza w pliku wywołujemy metodę Close w celu zamknięcia pliku Test.txt. Następnie stosujemy poniższy wiersz kodu w celu utworzenia nowego pliku tekstowego o nazwie C:\Scripts\Everyone.txt:

Set objFile = objFSO.CreateTextFile("C:\Scripts\Everyone.txt")

Jak można się było domyślać, do tego pliku wpiszemy dane pobrane z pliku Test.txt, zrobimy to za pomocą metody Write, przekazując metodzie zmienną strContents:

objFile.Write strContents

Teraz zamykamy plik Everyone.txt i sprawdzamy jego zawartość, powinniśmy zobaczyć coś takiego:

\\MBPGPS1PRN-001\mbbetsb01

\\MBPGPS1PRN-002\mbbetsb01

\\MBPGPS2PRN-001\mbbet02

Innymi słowy, istnieją drukarki, do których dostęp ma grupa Everyone. (No cóż, zakładając, że o to właśnie chodzi w pliku Test.txt.)

I na tym zakończymy. Jak już mówiłem, teraz będę rozmyślał o tym, gdzie chciałbym się teraz znaleźć, żeby móc zatęsknić za domem.

 Do początku strony Do początku strony

Centrum skryptów - Systemy operacyjne