Mam plik tekstowy z 2 milionami linii. Każda linia ma dodatnią liczbę całkowitą. Próbuję utworzyć coś w rodzaju tabeli częstotliwości.
Plik wejściowy:
3
4
5
8
Dane wyjściowe powinny wynosić:
3
7
12
20
Jak mam to zrobić?
command-line
text-processing
Monty Harder
źródło
źródło
Odpowiedzi:
Z
awk
:$0
jest bieżącą linią. Tak więc dla każdej linii dodaję ją dototal
, ustawiam linię na nowątotal
, a następnie trailing1
jest skrótem awk - drukuje bieżącą linię dla każdego prawdziwego warunku i1
jako warunek jest oceniany na prawdziwy.źródło
print
można również użyć tego słowa ?print total}
zamiast$0 = total}1
{print(total += $0)}
W skrypcie python:
Używać
add_last.py
Uruchom go jako plik źródłowy i docelowy plik wyjściowy jako argumenty:
Wyjaśnienie
Kod jest raczej czytelny, ale szczegółowo:
Otwórz plik wyjściowy do zapisywania wyników
Otwórz plik wejściowy do odczytu według wiersza
Przeczytaj wiersze, dodając wartość nowego wiersza do sumy:
Zapisz wynik w pliku wyjściowym:
źródło
Dla żartu
Działa to przez ppending do każdej linii wejścia, a następnie przekazując wynik do kalkulatora gdzie
+p
dc
następnie
W
-e0
popycha argumentów0
nadc
stosie, aby zainicjować sumę.źródło
real 0m4.234s
W Bash:
źródło
real 0m53.116s
prawie minutę, na 1,3 miliona linii :)Aby wydrukować częściowe sumy liczb całkowitych podane na standardowym wejściu, po jednym w wierszu:
Przykład możliwy do uruchomienia .
Jeśli z jakiegoś powodu polecenie jest zbyt wolne; możesz użyć programu C:
Aby go zbudować i uruchomić, wpisz:
Przykład możliwy do uruchomienia .
UINTMAX_MAX
jest18446744073709551615
.Kod C jest kilka razy szybszy niż polecenie awk na moim komputerze dla pliku wejściowego wygenerowanego przez:
źródło
accumulate()
itertPrawdopodobnie chcesz czegoś takiego:
Objaśnienie polecenia:
sort -n <filename> | uniq -c
sortuje dane wejściowe i zwraca tabelę częstotliwości| awk 'BEGIN{print "Number\tFrequency"}{print $2"\t"$1}'
zamienia wyjście w ładniejszy formatPrzykład:
plik wejściowy
list.txt
:Komenda:
źródło
Możesz to zrobić w vimie. Otwórz plik i wpisz następujące naciśnięcia klawiszy:
Zauważ, że
<C-a>
tak naprawdę to ctrl-a i<cr>
to powrót karetki , tzn. Przycisk Enter.Oto jak to działa. Po pierwsze, chcemy wyczyścić rejestr „a”, aby po raz pierwszy nie miał żadnych skutków ubocznych. To jest po prostu
qaq
. Następnie wykonujemy następujące czynności:Po zakończeniu działania tego rekurencyjnego makra, po prostu wywołujemy,
:wq<cr>
aby zapisać i wyjść.źródło
Perl One-Liner:
Przy 2,5 milionach linii liczb przetworzenie zajmuje około 6,6 sekundy:
źródło
real 0m0.908s
, całkiem miły.Prosta wyściółka Bash:
x
to skumulowana suma wszystkich liczb z bieżącej linii i powyżej.n
to liczba w bieżącym wierszu.Mamy pętla nad wszystkimi liniami
n
odINPUT_FILE
i dodać ich wartość numeryczną do naszej zmiennejx
i wydrukować tę sumę podczas każdej iteracji.Bash jest tu jednak trochę powolny, możesz oczekiwać, że uruchomi się to około 20-30 sekund dla pliku z 2 milionami wpisów, bez drukowania danych wyjściowych na konsoli (co jest jeszcze wolniejsze, niezależnie od używanej metody).
źródło
Podobne do odpowiedzi @ steeldriver, ale z nieco mniej tajemnym
bc
:Zaletą
bc
(idc
) jest to, że są one dowolnymi kalkulatorami precyzji, więc nigdy nie przepełnią się ani nie odczują braku precyzji w stosunku do liczb całkowitych.sed
Wyrażenie przekształca dane wejściowe do:Jest to następnie oceniane przez
bc
.a
Zmienna bc jest automatycznie inicjowany na 0. Każdy przyrosty liniowea
, a następnie wyraźnie drukuje go.źródło
real 0m5.642s
na 1,3 mln linii. sed jest bardzo powolny.