2012-12-18 14 views
7

Przepraszam, jeśli tytuł nie pasuje do mojego pytania, nadal nie jestem pewien, jak powinienem go umieścić.Polecenie Otwórz/Odczyt w Tcl 8.5 dla dużych plików

W międzyczasie używam Tcl/Tk na Windowsie (wish) od jakiegoś czasu i nie napotkałem żadnego problemu na skrypcie, który napisałem do niedawna. Skrypt ma rozbić duży plik txt na mniejsze pliki, które można zaimportować do programu Excel (mówię o rozbijaniu pliku z około 25 milionami linii, który wynosi około 2,55 GB).

Mój obecny skrypt jest coś takiego:

set data [open "file.txt" r] 
set data1 [open "File Part1.txt" w] 
set data2 [open "File Part2.txt" w] 
set data3 [open "File Part3.txt" w] 
set data4 [open "File Part4.txt" w] 
set data5 [open "File Part5.txt" w] 


set count 0 
while {[gets $data line] != -1} { 
    if {$count > 4000000} { 
     puts $data5 $line 
    } elseif {$count > 3000000} { 
     puts $data4 $line 
    } elseif {$count > 2000000} { 
     puts $data3 $line 
    } elseif {$count > 1000000} { 
     puts $data2 $line 
    } else { 
     puts $data1 $line 
    } 
    incr count 
} 

close $data 
close $data1 
close $data2 
close $data3 
close $data4 
close $data5 

I zmieniać numery wewnątrz if aby uzyskać żądaną liczbę wierszy na plik lub dodać/usunąć elseif gdzie wymagane.

Problem polega na tym, że w najnowszym pliku mam tylko połowę danych (1,22 GB zamiast 2,55 GB) i zastanawiałem się, czy istnieje linia, która powiedziała Tcl, aby zignorować ograniczenie, można przeczytać. Próbowałem go szukać, ale nie znalazłem nic (ani niczego, co mógłbym dobrze zrozumieć, nadal jestem amatorem w Tcl ^^;). Czy ktoś może mi pomóc?

EDIT (zmiana): Znalazłem program do otwierania dużych plików tekstowych i udało się uzyskać podgląd zawartości pliku bezpośrednio. W rzeczywistości jest 16 756 263 linii. Zmieniłem skryptu:

set data [open "file.txt" r] 
set data1 [open "File Part1.txt" w] 

set count 0 
while {[gets $data line] != -1} { 
    incr count 
} 
puts $data1 $count 
close $data 
close $data1 

dostać gdzie skrypt blokuje i zatrzymał się tutaj: enter image description here

Jest to postać, że edytor tekstu nie rozpoznaje w środkowej linii pokazano jako placyku . Próbowałem użyć fconfigure, tak jak sugerował to zły otto, ale obawiam się, że nie bardzo rozumiem, w jaki sposób channelID, name lub value działa dokładnie tak, aby uciec przed tą postacią. Um ... pomoc?

REEDIT: Udało mi się dowiedzieć, jak działał fconfigure! Dzięki Zło otto! Nie jestem pewien, jak mogę "wybrać" twoją odpowiedź, ponieważ jest to komentarz zamiast właściwej odpowiedzi ...

+0

Czy 1.22 to łączny rozmiar plików wynikowych? Czy plik wejściowy jest tekstem lub plikiem binarnym? – pn8830

+3

To powinno zadziałać; obsługa dużych plików została dodana w wersji 8.4 i nie próbujesz odczytać wszystkich danych naraz ... –

+5

Czy jest możliwe, że jakieś dane binarne znajdują się w "file.txt"? W oknach tcl zaznaczy eof, jeśli odczyta plik '^ Z' (domyślny' eofchar'). Możesz wyłączyć to za pomocą 'fconfigure' - zobacz dokumentację po szczegóły. –

Odpowiedz

2

Czy jest możliwe, że w pliku "file.txt" są jakieś dane binarne? Pod Windowsem tcl zaznaczy eof, jeśli odczyta w pliku ^Z (domyślnie).Można to wyłączyć z fconfigure:

fconfigure $data -eofchar {} 

Zobacz docs dla pełnych szczegółów.

1

Uruchomiłem twój skrypt na Macu, który jest oparty na Uniksie i zauważyłem, co następuje:

  1. Numer incr count powinien znajdować się na początku pętli - pomniejszy punkt.
  2. Co ważniejsze, plik.txt zawiera linie 25m, ale ty podzielony nierównomiernie: pierwsze cztery każda zawiera 1M, a reszta idzie do File5.txt. Jeśli chcesz równomiernie podzielić pliki, punkty przerwania powinny wynosić 20M, 15M, 10M i 5M.
  3. Poza tym nie zauważyłem utraty danych. Nie mam komputera z systemem Windows, aby go przetestować.
+0

Um, tak, odpowiednio dostosowuję skrypt, więc nie tracę danych. Powyższe było tylko próbką skryptu podobną do tej, której użyłem. – Jerry

Powiązane problemy