Centrum skryptów - Systemy operacyjne

Jak usunąć z pliku tekstowego każdy wiersz zawierający określoną wartość ciągu?

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 usunąć z pliku tekstowego każdy wiersz zawierający określoną wartość ciągu?

Cześć Skrypciarze! Pytanie

Cześć Skrypciarze! Jak usunąć każdy wiersz w pliku tekstowym, który zawiera ciąg f0?

-- CJ

Cześć Skrypciarze! Odpowiedź

Cześć, CJ. Bardzo źle się dzisiaj czuję. Nie wiem dokładnie, co mi dolega, ale tak się czuję, że mam wrażenie, że wszystko. Boli mnie nawet, kiedy myślę. Wszyscy dookoła twierdzą, że wyglądam normalnie, ale co oni mogą wiedzieć na temat tego, co przeżywa mój organizm. Toczy on jakąś wewnętrzną walkę, której efekt widoczny będzie dopiero za kilka godzin. Nie chcę was jednak zanudzać opowieściami o moich dolegliwościach, chciałem się tylko trochę usprawiedliwić i wyjaśnić, dlaczego nie będzie dzisiaj żadnej zabawnej historii ani anegdoty.

Po prostu przejdę do rzeczy, czyli do skryptu, który usunie z naszego pliku tekstowego wszystkie wiersze posiadające ciąg f0.

Na początek, wyobraźmy sobie, że nasz plik tekstowy wygląda następująco (C:\Scripts\Test.txt):

This line should stay.

This line (f0) should be deleted.

This line should also be deleted. (f0)

This line should not be deleted.

This line should remain.

f0: This last line should be deleted.

Zastanówmy się przez chwilę, co możemy zrobić, żeby usunąć z tego skryptu wszystkie wiersze i tylko te wiersze, które zawierają f0.

Ja ze swojej strony proponuję zastosowanie poniższego skryptu:

Const ForReading = 1

Const ForWriting = 2



Set objFSO = CreateObject("Scripting.FileSystemObject")

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



Do Until objFile.AtEndOfStream

    strLine = objFile.ReadLine

    If InStr(strLine, "f0") = 0 Then

        strNewContents = strNewContents & strLine & vbCrLf

    End If

Loop



objFile.Close



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

objFile.Write strNewContents



objFile.Close

Jak on działa? No cóż, na początek definiujemy parę stałych ForReading oraz ForWriting; wykorzystamy je podczas otwierania pliku tekstowego. (Będziemy musieli otworzyć ten plik dwa razy: raz w celu wczytania bieżącej zawartości pliku do pamięci i drugi - w celu wpisania zmodyfikowanej zawartości z powrotem do pliku.) Po zdefiniowaniu tych dwóch stałych tworzymy wystąpienie obiektu Scripting.FileSystemObject, a następnie stosujemy poniższy wiersz kodu w celu otwarcia pliku C:\Scripts\Test.txt do odczytu:

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

Na tym jeszcze nie koniec, długa do tego droga przed nami. Po otwarciu naszego pliku tekstowego do odczytu stosujemy następujący wiersz kodu:

Do Until objFile.AtEndOfStream

    strLine = objFile.ReadLine

    If InStr(strLine, "f0") = 0 Then

        strNewContents = strNewContents & strLine & vbCrLf

    End If

Loop

Dobre pytanie: co się teraz dzieje? Na początek uruchamiamy pętlę Do Until, która będzie działać, dopóki nie dotrze do końca pliku. (Lub też, innymi słowy, dopóki właściwość AtEndOfStream pliku ma wartość True.) Wewnątrz tej pętli odczytamy cały plik, wiersz po wierszu; do tego posłuży nam poniższy wiersz kodu (oraz metoda ReadLine):

strLine = objFile.ReadLine

Jak można się było spodziewać, przy pierwszym przejściu pętli odczytamy pierwszy wiersz pliku tekstowego i zachowamy tę wartość w zmiennej strLine. (Na wypadek, gdyby ktoś zapomniał, pierwszy wiersz w pliku tekstowym to: This line should stay.)

Teraz musimy określić, czy wartość ciągu f0 pojawia się gdzieś w tym wierszu pliku. Jak to zrobić? Za pomocą funkcji InStr języka VBScript oczywiście:

If InStr(strLine, "f0") = 0 Then

Funkcja InStr analizuje wartość ciągu (podobnie jak zmienna strLine) i przekazuje pozycję znaku, na której znajduje się docelowy tekst (f0). Na przykład, jeżeli zmienna strLine miała wartość 123f0, funkcja InStr przekaże wartość 4. Dlaczego? Ponieważ docelowy tekst zaczyna się od czwartej pozycji znaku:

Pozycja 1 Pozycja 2 Pozycja 3 Pozycja 4 Pozycja 5
1 2 3 f 0

Co się dzieje w przypadku, gdy nie można znaleźć tekstu docelowego, jak to jest w pierwszym wierszu tekstu? Funkcja InStr przekazuje wartość 0.

Fakt, że funkcja InStr przekazuje wartość 0, gdy nie można znaleźć w wierszu tekstu docelowego, może być bardzo przydatny. Jeżeli funkcja InStr przekaże coś innego niż 0, będzie to oznaczać, że tekst docelowy został odnaleziony gdzieś w ciągu strValue; to z kolei oznacza, że jest to wiersz, który należy usunąć. Dlatego też, jeżeli otrzymamy wartość inną niż 0, nie robimy już nic. Po prostu ignorujemy ten wiersz. Jeżeli jednak otrzymamy wartość 0 (czyli informację, że nie odnaleziono tekstu docelowego), wykonujemy następujący wiersz kodu:

strNewContents = strNewContents & strLine & vbCrLf

To powinno być całkiem proste, wystarczy przypisać wartość do zmiennej o nazwie strNewContents, wartość składającą się z następujących elementów:

  • Bieżąca wartość strNewContents (bieżąca wartość to pusty ciąg przy pierwszym przejściu pętli).
  • Wiersz pliku, który właśnie wczytaliśmy z pliku tekstowego (reprezentowany przez zmienną variable strLine).
  • Znak powrotu karetki (reprezentowany przez stałą vbCrLf języka VBScript).

Teraz kontynuujemy działanie pętli i powtarzamy proces dla następnego wiersza w pliku.

Zanim dotrzemy do końca pliku zmienna strNewContents będzie miała następującą wartość, która – tak się składa – jest zawartością pliku tekstowego minus wiersze zawierające ciąg f0:

This line should stay.

This line should not be deleted.

This line should remain.

W tym momencie przynajmniej plik nie został zmieniony. Ale to możemy naprawić. Po zamknięciu pliku (pliki tekstowe mogą być otwierane do odczytu lub do zapisu, ale nie w celu dokonania obydwu tych czynności, przynajmniej nie w tym samym czasie) otwieramy go od razu, tym razem do zapisu:

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

Teraz wystarczy wywołać metodę Write i zapisać zmodyfikowaną zawartość (wartość zmiennej strNewContents) w pliku tekstowym:

objFile.Write strNewContents

Następnie zamykamy plik tekstowy po raz ostatni i no już jest koniec naszej pracy.

Całe szczęście, bo moja gorączka chyba się trochę podniosła. Rety, jak ja cierpię.

 Do początku strony Do początku strony

Centrum skryptów - Systemy operacyjne