Mam plik, który jest zbyt duży, aby zmieścić się w pamięci. shuf
wydaje się działać w pamięci RAM, a sort -R
nie tasuje (identyczne linie kończą się obok siebie, potrzebuję przetasowania wszystkich linii). Czy są jakieś inne opcje niż przetaczanie własnego rozwiązania?bash - tasuje plik, który jest zbyt duży, aby zmieścił się w pamięci
Odpowiedz
Korzystanie formę decorate-sort-undecorate wzór i awk
można zrobić coś takiego:
$ seq 10 | awk 'BEGIN{srand();} {printf "%06d %s\n", rand()*1000000, $0;}' | sort -n | cut -c8-
8
5
1
9
6
3
7
2
10
4
przypadku pliku, należy zrobić:
$ awk 'BEGIN{srand();} {printf "%06d %s\n", rand()*1000000, $0;}' SORTED.TXT | sort -n | cut -c8- > SHUFFLED.TXT
lub cat
plik na początku potoku.
Działa to poprzez generowanie kolumny liczb losowych między 000000
i 999999
włącznie (dekorowanie); sortowanie w tej kolumnie (sortowanie); następnie usunięcie kolumny (bez dekoracji). To powinno działać na platformach, na których sortowanie nie rozumie liczb, generując kolumnę z wiodącymi zerami do sortowania leksykograficznego.
Można zwiększyć tę randomizacji, w razie potrzeby, na kilka sposobów:
Jeśli platformy
sort
rozumie wartości liczbowe (POSIX, GNU oraz BSD zrobić) można zrobićawk 'BEGIN{srand();} {printf "%0.15f\t%s\n", rand(), $0;}' FILE.TXT | sort -n | cut -f 2-
używać w pobliżu Double pływakowy reprezentacja losowa.Jeśli są ograniczone do leksykograficznego rodzaju, po prostu połączyć dwa połączenia do
rand
do jednej kolumny tak:awk 'BEGIN{srand();} {printf "%06d%06d\t%s\n", rand()*1000000,rand()*1000000, $0;}' FILE.TXT | sort -n | cut -f 2-
co daje kompozytowego 12 cyfr randomizacji.
Policz linie (wc -l
) i wygeneruj listę liczb odpowiadającą numerom linii, w losowej kolejności - być może poprzez wygenerowanie listy liczb w pliku tymczasowym (użyj /tmp/
, która jest zwykle w pamięci RAM, a zatem stosunkowo szybko). Następnie skopiuj linię odpowiadającą każdemu z numerów do pliku docelowego w kolejności numerów przetasowanych.
Byłoby to czasowo nieefektywne ze względu na ilość poszukiwania nowych linii w pliku, ale działałoby prawie na każdym rozmiarze pliku.
Jak o: perl <large-input-file -lne 'print rand(), "\t", $_' | sort | perl -lpe 's/^.*?\t//' >shuffled-output-file
Jeśli plik jest w ciągu kilku rzędów wielkości, co zmieści się w pamięci, jedną z opcji jest losowo rozpowszechniać linie pomiędzy (powiedzmy) 1000 plików tymczasowych, a następnie losowo każdy z tych plików i złączyć wynik :
perl -we ' my $NUM_FILES = 1000;
my @fhs;
for (my $i = 0; $i < $NUM_FILES; ++$i) {
open $fh[$i], "> tmp.$i.txt"
or die "Error opening tmp.$i.txt: $!";
}
while (<>) {
$fh[int rand $NUM_FILES]->print($_);
}
foreach my $fh (@fhs) {
close $fh;
}
' < input.txt \
&& \
for tmp_file in tmp.*.txt ; do
shuf ./"$tmp_file" && rm ./"$tmp_file"
done > output.txt
(oczywiście będą pewne różnice w rozmiarach plików tymczasowych — nie wszystko będzie dokładnie jedna tysięczna rozmiar oryginalnego pliku — więc jeśli używasz tego podejścia , musisz dać sobie trochę bufora, wybierając z boku więcej, mniejsze pliki.)
Przepraszam za wstępne błędne odczytanie - mam nadzieję, że osoba przekazująca nie ufała mojej błędnej analizie. Jest to całkowicie rozsądne podejście. –
@CharlesDuffy: Bez obaw. Domyślam się, że downwizerem był l'l'l. (A nawet jeśli nie, teraz myślę, że odpowiedź dawga jest lepszym podejściem niż moje, więc nie jestem zbyt przywiązany do tej odpowiedzi. :-P) – ruakh
Spójrz na https://github.com/alexandres/terashuf.Od strony:
terashuf implementuje algorytm quasi-losowego do tasowania wieloterabajtowe plików tekstowych za pomocą ograniczoną pamięć
- 1. W języku Java jest jakiś sposób losowania pliku, który jest zbyt duży, aby zmieścił się w pamięci?
- 2. Plik pikli zbyt duży, aby załadować
- 3. IOS - W jaki sposób AES odszyfrowuje duży plik, jeśli plik jest zbyt duży, aby załadować go do pamięci?
- 4. wykryć, czy przesłany plik jest zbyt duży
- 5. Wizualizacja niekierowanego wykresu, który jest zbyt duży dla GraphViz?
- 6. WebView w ScrollView: "Widok zbyt duży, aby zmieścić się w pamięci podręcznej rysunku" - jak przerobić układ?
- 7. WebView i GridView w ScrollView, Widok zbyt duży, aby zmieścić się w pamięci podręcznej rysunku
- 8. Projekt Java staje się zbyt duży
- 9. Przesyłanie pliku Golang: bliskie połączenie, jeśli plik jest zbyt duży.
- 10. Zbyt duży rozmiar pliku dziennika w szynach
- 11. Przepisz mapy w IIS Spraw, aby web.config był zbyt duży.
- 12. Jak zmienić rozmiar UILabel, aby zmieścił się w tekście
- 13. JAVA -tomcat- Nagłówek żądania jest zbyt duży
- 14. Zmień rozmiar obrazu, aby zmieścił się w ramce ograniczającej
- 15. Szyny: zbyt duży poziom stosu
- 16. Zmień rozmiar obrazu, aby zmieścił się w dziale
- 17. Duży plik blob w JavaScript
- 18. Zmienianie rozmiaru emulatora Androida, aby zmieścił się na moim ekranie
- 19. Strumień pamięci i duży obiekt
- 20. Aby skompresować duży plik w ZIP z Javą
- 21. 400 Złe żądanie - nagłówek żądania lub plik cookie zbyt duży
- 22. CKAN: Przesyłanie do magazynu danych nie powiodło się; Zasób zbyt duży, aby pobrać
- 23. Jak duży może być plik mapowany w pamięci?
- 24. Wymuś obraz, aby zmieścił się i zachował proporcje obrazu
- 25. Zmień rozmiar TEKSTU, aby zmieścił się na UITextView
- 26. Webpack: Jak zoptymalizować wygenerowany plik bundle.js? Jest zbyt duży w moim przypadku.
- 27. Plik śledzenia TextWriterTraceListener za duży
- 28. Podziel duży plik tekstowy CSV na podstawie wartości kolumny
- 29. skuteczny sposób, aby podzielić duży plik tekstowy w Pythonie
- 30. Błąd przesunięcia jest ujemny lub zbyt duży - poprawne rozwiązanie?
Nicea. Ponieważ "sort" dzieli się na wiele plików, aby przetwarzać zawartość większą niż zmieści się w pamięci (w każdym razie wersja GNU), powinno to faktycznie zadziałać. –
+1 - dobry pomysł. Zauważ, że skoro "sort" wykonuje sortowanie stabilne, nie będzie to 100% perfekcyjnego tasowania: jeśli linia A występuje przed linią B na wejściu, to podejście jest nieco bardziej prawdopodobne, aby umieścić linię A przed linią B na wyjściu. Aby to naprawić, możesz odwrócić numerowanie i tasowanie, pisząc coś w stylu 'seq 10 | grep -n '' | sortuj -R | cut -d: -f2-'zamiast tego. (Ale nawet bez tej zmiany, myślę, że to prawdopodobnie w porządku: myślę, że powinno to być całkiem bliskie losowej kolejności.) – ruakh
@ruakh: Dzięki. Masz rację - ma niewielką tendencję do utrzymywania porządku z powodu "sortowania" o stabilnym sortowaniu. Ma losowe cyfry od 0 do 1000000, więc byłby to problem tylko z tą samą liczbą losową w dwóch wierszach w rzędzie. Innym sposobem na uczynienie go bardziej losowym jest dodanie większej liczby cyfr lub drugiej kolumny losowych cyfr. – dawg