Centrum skryptów - Systemy operacyjne

Jak usunąć niepożądane znaki tabulacji z plików tekstowych?

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ąć niepożądane znaki tabulacji z plików tekstowych?

Cześć Skrypciarze! Pytanie

Cześć, Skrypciarze! Mam około 5.000 plików tekstowych, które zawierają niepotrzebne znaki tabulacji na końcu każdego wiersza. Czy istnieje jakiś skrypt, który uporałby się z tym problemem?

-- TT

Cześć Skrypciarze! Odpowiedź

Cześć, TT! Widzisz, Twoim problemem są niepotrzebne znaki tabulacji, ja natomiast borykam się tu z… no w sumie nie wiem czym. Chociaż prawdę mówiąc wiem, ale nie wiem, czy wypada umieścić na skrypciarskich łamach jeszcze raz słowo „baseball”. Skrypciarska Pani Redaktor sugeruje, że powinienem napisać skrypt, który usuwa wszystkie słowa „baseball” ze wszystkich skryptów mojego autorstwa (chociaż moim zdaniem to jedno z ładniejszych i bardziej potrzebnych słów w słowniku).

Chociaż Twój problem, nie powiem,

jest równie ekscytujący jak …

(brak tu tego słowa, uruchomiłem skrypt,

który usuwa wszystkie słowa … od tego akapitu, aż do

końca moich artykułów, które notabene nie powstały

jeszcze nawet w mojej głowie.)

Oto więc skrypt, który usuwa wszystkie niepotrzebne Ci

(mnie być może też się on kiedyś przyda)

znaki tabulacji:

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 Right(strLine, 1) = Chr(9) Then

        intLength = Len(strLine)

        strLine = Left(strLine, intLength - 1)

        strContents = strContents & strLine & vbCrLf

    End If

Loop



objFile.Close



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



objFile.Write strContents



objFile.Close

Zaczynamy (jak zwykle) od zdefiniowania pary stałych (ForReading oraz ForWriting), których będziemy używać podczas otwierania pliku. Po ich zdefiniowaniu tworzymy wystąpienie obiektu Scripting.FileSystemObject, a następnie używamy metody OpenTextFile i otwieramy plik C:\Scripts\Test.txt do odczytu:

Set objFSO = CreateObject("Scripting.FileSystemObject")

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

Gdy plik jest już otwarty, ustawiamy pętlę Do Until, która przechodzi przez plik aż do momentu, w którym jego właściwość AtEndOfStream przyjmie wartość True. (To oczywiście popisowe zdanie nie mówiące nic innego, jak to, że pętla będzie działać, dopóki nie przejdzie przez cały plik.) Wewnątrz pętli korzystamy z metody ReadLine i odczytujemy pierwszy wiersz pliku, przechowując go w zmiennej strLine:

strLine = objFile.ReadLine

To sprowadza nas do następującego wiersza kodu:

If Right(strLine, 1) = Chr(9) Then

Chociaż TT napisała, że u niej każda linijka kończy się niepotrzebnym znakiem tabulatora, my potraktowaliśmy to z „z taką pewną nieśmiałością” i postanowiliśmy sprawdzić, czy dany wiersz kończy się rzeczywiście takim znakiem. Jak to zrobiliśmy? Użyliśmy funkcji Right, która sprawdza ostatni znak wersu. Jeżeli znak ma ASCII równą 9, to oznacza to dla nas tylko jedną rzecz: to znak tabulatora, co z kolei oznacza, że trzeba się go jak najprędzej pozbyć.

Jak pozbywamy się takiego niechcianego znaku tabulatora z końca? Już odpowiadam: najpierw korzystamy z Len, która ustala nam całkowitą liczbę znaków w ciągu i przechowuje tę wartość w zmiennej intLength. Następnie używając funkcji Left pobieramy wszystkie znaki oprócz ostatniego (dlatego właśnie użyliśmy z konstrukcji intLength – 1). Załóżmy, że naszym ciągiem jest: cat. Długość tego ciągu (czyli liczba znaków) to 3. Długość taka minus 1 to oczywiście… dwa (nie, znak „…” służy tym razem jako pauza, a nie zabronione słowo …). Oznacza to, ze nasz nowy ciąg będzie się równał: ca.

Mam nadzieję, ze wyjaśnienia są zrozumiałe.

Teraz używamy poniższego wiersza kodu, aby dodać zmodyfikowaną wartość ciągu (plus znak powrotu i karetki) do zmiennej strContents:

strContents = strContents & strLine & vbCrLf

Następnie uruchamiamy pętlę i powtarzamy proces dla kolejnego wiersza w pliku, usuwając niechciane znaki tabulatora i doczepiając zmodyfikowany wiersz na końcu wartości strContents. Itp., itd.

Zanim wyjdziemy z pętli, będziemy mieli utworzoną zupełnie nową wersję pliku w pamięci, taką, z której usunięte zostały wszystkie niepotrzebne znaki tabulatora. Aby zapisać tę wersję z powrotem do naszego pliku (C:\Scripts\Test.txt), musimy najpierw zamknąć plik, a następnie otworzyć go ponownie za pomocą metody OpenTextFile, tym razem w celu zapisu:

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

Po otwarciu pliku używamy metody Write i zapisujemy nową wersję pliku do Test.txt. Teraz przywołujemy już tylko metodę Close i zamykamy plik.

Dobre pytanie: dlaczego nie użyliśmy po prostu funkcji Replace i nie pozbyliśmy się wszystkich znaków tabulatora? Oczywiście mogliśmy to zrobić, ale zakładamy, że oprócz znaków tabulacji na końcu wersów, w pliku mogą znajdować się również inne takie znaki, których usuwać nie należy. Metoda Replace usunęłaby po prostu wszystkie znaki tabulatora. Powyższy skrypt usuwa te znaki tylko z końca wersów.

Teraz uprzedzimy kolejne zapytanie TT: co zrobić, jeżeli niektóre wersy mają więcej niż jeden niechciany znak tabulatora na końcu linijki? Na wszystko znajdzie się metoda. Oto zmodyfikowana pętla Do, która zawiera drugą pętlę Do Until; druga pętla sprawdza, jaki jest ostatni znak ciągu, i jeżeli jest to znak tabulatora, to go usuwa, następnie sprawdza ostatni znak zmodyfikowanego ciągu i, znowu, jeżeli jest to znak tabulatora, usuwa go. I tak dalej, i tak dalej, aż usunie wszystkie znaki tabulatora z końca wersu.

Oto zmodyfikowany kod:

Do Until objFile.AtEndOfStream

    strLine = objFile.ReadLine

    Do Until i = 100

        If Right(strLine, 1) = Chr(9) Then

            intLength = Len(strLine)

            strLine = Left(strLine, intLength - 1)

        Else

            Exit Do

        End If

    Loop

    strContents = strContents & strLine & vbCrLf

Loop

Zobaczmy teraz czy nasz skrypt zadziałał:

Chociaż Twój problem, nie powiem, jest równie ekscytujący jak … (brak tu tego słowa, uruchomiłem skrypt, który usuwa wszystkie słowa … od tego akapitu, aż do końca moich artykułów, które notabene nie powstały jeszcze nawet w mojej głowie.) Oto więc skrypt, który usuwa wszystkie niepotrzebne Ci (mnie być może też się on kiedyś przyda) znaki tabulacji:

Chyba się przydał. Nie, żartuję, usunąłem to oczywiście ręcznie.

 Do początku strony Do początku strony

Centrum skryptów - Systemy operacyjne