Gdzie możemy pobrać numery?

0

Potrzebujemy pliku zawierającego liczby:

0000000000..1000000000

i

0..1000000000

skąd możemy pobrać tego rodzaju listy?

Przykład 1:

000000001
000000002
...
099999999
100000000

Przykład 2: 1 2 ... 999999999 1000000000

Jeśli szukam stron z torrentami lub tylko Google, mogę znaleźć tylko pliki zawierające ~ 8 cyfr, ale potrzebujemy 10.

Próbowaliśmy wygenerować te pliki:

var=0; while true; do var=$((var+1)); echo $var >> sorted-generated-only-numbers-length-from-1-to-10-chars-zero-at-start-too.txt; done

ale wygenerowanie pliku zajmie wieki, nawet na większej maszynie. Poważnie..

AKTUALIZACJA: Próbowaliśmy użyć: var = 0; var2 = 100000; chociaż prawda; do tmpbuffer100k = $ (sekw. $ var $ var2; var = $ ((var + 100000)); var2 = $ ((var2 + 100000))); echo „$ tmpbuffer100k” >> output.txt; gotowy

aby uniknąć zapisu na dysk, zamiast tego umieszczamy np .: 100 000 liczb w zmiennej, a następnie zapisujemy ją na dysku - aby przyspieszyć, ale jeszcze nie działa. Zapisuje tylko pierwszy zakres, 1..100000

pepite
źródło
1
Twoje obecne podejście otwiera plik dla każdej zapisanej linii. To niesamowicie nieefektywne. Ty też nigdy nie przestajesz ...?
Daniel B,
Będę CTRL + C, gdy skończy się, ale gdybym dodał „jeśli osiągnięto wystarczającą liczbę wyjść 0”, byłoby wolniej. Sugerujesz więc, aby umieścić liczby w zmiennej, a kiedy osiągniesz bardzo wysoką liczbę, wyślij ją do pliku?
pepite
6
Brzmi zupełnie jak problem XY , po co ci to?
gronostaj

Odpowiedzi:

4

Oto wydajne rozwiązanie pure Bash:

function print_numbers {
  current_num=$1
  target_num=$2
  target_num_length=${#target_num}

  while [ $current_num -le $target_num ]; do
    printf "%0${target_num_length}d\n" $current_num
    # or just "echo $current_num" if padding is not required
    current_num=$((current_num + 1))
  done
}

print_numbers 0 10 > target_file

Ponieważ wykorzystuje tylko wbudowane Bash, nie są tworzone żadne dodatkowe procesy. Otwiera plik target_file raz i przekierowuje wszystkie dane wyjściowe z funkcji do tego pliku.

Funkcja przerywa się automatycznie po osiągnięciu wartości docelowej.

Oczywiście, w porównaniu z rodzimym narzędziem, takim jak seq, wciąż jest niesamowicie wolny:

db-nb-13:~ fuzzy$ time print_numbers 0 100000 > /dev/null

real    0m2.909s
user    0m2.761s
sys 0m0.139s
db-nb-13:~ fuzzy$ time print_numbers 0 1000000 > /dev/null

real    0m30.974s
user    0m29.074s
sys 0m1.651s

db-nb-13:~ fuzzy$ time seq -w 0 1000000 > /dev/null

real    0m0.370s
user    0m0.363s
sys 0m0.003s

Ostrzeżenie

Pliki wynikowe będą bardzo duże. Plik zawierający 0..1000000000, wypełniony zerami, będzie miał

1 000 000 000 * (10 (bytes for 10 digits – ASCII!) + 1 (newline)) = 11 000 000 000 bytes

To 10,24 GiB ! Ty naprawdę powinna ponownie rozważyć swoje podejście do problemu, co starasz się rozwiązać.

Daniel B.
źródło
4
+1 za samo ostrzeżenie. Tak dziwnym wymogiem jest czerwona flaga. 10 GB kolejnych numerów prawdopodobnie nie jest rozwiązaniem, ale częścią zepsutego rozwiązania zupełnie innego problemu.
gronostaj
4

Sprawdźmy najpierw rozwiązanie na przykład 2:

W systemie Linux masz seqna przykład:

seq 099999990 100000000

wydrukuje tę listę:

99999990
99999991
99999992
99999993
99999994
99999995
99999996
99999997
99999998
99999999
100000000

Skieruj wyjście do pliku:

seq 1 100000000 > the_file.txt

Teraz, gdy rozumiesz, jak seqdziała, wróćmy do przykładu 1 :

Jeśli dodasz do seqflagi -f, możesz dodać dopełnienie do wygenerowanej sekwencji, na przykład:

seq -f "%05g" 1 10

Dodanie dopełnienia do każdej liczby w celu sformatowania jej jako 5 cyfr:

00001
00002
00003
00004
00005
00006
00007
00008
00009
00010

W konkretnym przypadku musisz użyć, -f "%010g"aby uzyskać 10-cyfrowe długie liczby.

jcbermu
źródło
-wFlaga jest szybszy sposób, aby uzyskać dopełnienie do wysokości cyfr w górnej granicy.
Daniel B