W skrypcie Bash chcę wybrać N losowych linii z pliku wejściowego i wyprowadzić do innego pliku.
Jak można to zrobić?
bash
shell
random
text-processing
użytkownik121196
źródło
źródło
sort -R
ponieważ powoduje to nadmierną pracę, szczególnie w przypadku długich plików. Można użyć$RANDOM
,% wc -l
,jot
,sed -n
(à la stackoverflow.com/a/6022431/563329 ) i funkcjonalność bash (tablice, przekierowania poleceń, etc), aby zdefiniować własnąpeek
funkcję, która będzie faktycznie działać na plikach 5.000.000 linii.Odpowiedzi:
Użyj
shuf
tej-n
opcji, jak pokazano poniżej, aby uzyskaćN
losowe linie:źródło
sort -R
?Sortuj plik losowo i wybierz pierwsze
100
wiersze:źródło
sort
faktycznie sortuje identyczne linie razem, więc jeśli możesz mieć zduplikowane linie i maszshuf
(narzędzie GNU) zainstalowane, lepiej do tego użyć.shuf -n
działa dość natychmiastowo.sort -R
jest prawdopodobnie opcją GNU, zainstaluj GNU coreutils. btw,shuf
jest również częścią coreutils.sort -R input | head -n <num_lines>
. Plik wejściowy miał 279 GB, z liniami 2bi +. Nie mogę tego jednak udostępnić. W każdym razie chodzi o to, że możesz zachować niektóre linie w pamięci za pomocą losowego wybierania, aby dokonać losowego wyboru tego, co chcesz wydrukować. Sortowanie posortuje cały plik, niezależnie od twoich potrzeb.Cóż Zgodnie z komentarzem do odpowiedzi shuf przetasował 78 000 000 000 linii w niecałą minutę.
Wyzwanie przyjęte...
Najpierw potrzebowałem pliku 78.000.000.000 linii:
To daje mi plik z 78 miliardami nowych linii ;-)
Teraz część shuf:
Wąskim gardłem był procesor i nie używający wielu wątków, przypiął 1 rdzeń na 100%, a pozostałych 15 nie było używanych.
Python jest tym, czego regularnie używam, więc tego użyję, aby przyspieszyć:
To dało mi niecałą minutę:
Zrobiłem to na Lenovo X1 Extreme 2. generacji z i9 i Samsung NVMe, co daje mi dużą prędkość odczytu i zapisu.
Wiem, że może być szybciej, ale zostawię trochę miejsca, aby dać innym szansę.
Źródło licznika linii : Luther Blissett
źródło