Bash
Równolegle
Szukaj…
Wprowadzenie
Zadania w GNU Linux mogą być równoległe przy użyciu GNU równoległego. Zadanie może być pojedynczym poleceniem lub małym skryptem, który należy uruchomić dla każdej linii na wejściu. Typowe dane wejściowe to lista plików, lista hostów, lista użytkowników, lista adresów URL lub lista tabel. Zadanie może być także poleceniem odczytującym z potoku.
Składnia
- równolegle [opcje] [polecenie [argumenty]] <lista_argumentów>
Parametry
Opcja | Opis |
---|---|
-jn | Uruchom n zadań równolegle |
-k | Zachowaj to samo zamówienie |
-X | Wiele argumentów z kontekstem zastępuje |
--colsep regexp | Podziel dane wejściowe w wyrażeniu regularnym dla zastępowania pozycji |
{} {.} {/} {/.} {#} | Łańcuchy zamienne |
{3} {3.} {3/} {3/.} | Pozycyjne ciągi zastępujące |
-S sshlogin | Example: [email protected] |
--trc {}.bar | Skrót od --transfer --return {} .bar --cleanup |
--onall | Uruchom podane polecenie z argumentem na wszystkich sshlogins |
--nonall | Uruchom podane polecenie bez argumentów na wszystkich sshlogins |
--pipe | Podziel standardowe wejście (standardowe wejście) na wiele zadań. |
--recend str | Zapisz separator końcowy dla --pipe. |
--recstart str | Rekord separatora początkowego dla --pipe. |
Zrównoleglaj powtarzalne zadania na liście plików
Wiele powtarzalnych zadań można wykonać wydajniej, jeśli wykorzystasz więcej zasobów komputera (tj. Procesora i pamięci RAM). Poniżej znajduje się przykład równoległego uruchamiania wielu zadań.
Załóżmy, że masz < list of files >
, powiedz wyjście z ls
. Pozwól też, aby pliki te były skompresowane do formatu BZ2 i należy wykonywać na nich następującą kolejność zadań.
- Zdekompresuj pliki
bzcat
za pomocąbzcat
na standardowe wyjście - Linie grep (np. Filtruj) z określonymi słowami kluczowymi używając
grep <some key word>
- Potokuj dane wyjściowe, które mają zostać skonkatenowane, do jednego pojedynczego pliku spakowanego
gzip
za pomocągzip
Uruchomienie tego za pomocą pętli while może wyglądać tak
filenames="file_list.txt"
while read -r line
do
name="$line"
## grab lines with puppies in them
bzcat $line | grep puppies | gzip >> output.gz
done < "$filenames"
Korzystając z GNU Parallel, możemy uruchomić 3 równoległe zadania jednocześnie, po prostu robiąc
parallel -j 3 "bzcat {} | grep puppies" ::: $( cat filelist.txt ) | gzip > output.gz
To polecenie jest proste, zwięzłe i wydajniejsze, gdy liczba plików i ich rozmiar są duże. Zadania są inicjowane parallel
, opcja -j 3
uruchamia 3 zadania równoległe, a dane wejściowe do zadań równoległych są pobierane przez :::
. Dane wyjściowe są ostatecznie przesyłane do gzip > output.gz
Równoległy STDIN
Teraz wyobraźmy sobie, że mamy 1 duży plik (np. 30 GB), który należy przekonwertować, linia po linii. Powiedzmy, że mamy skrypt, convert.sh
, który wykonuje to <task>
. Możemy potokować zawartość tego pliku do standardowego wejścia równoległego, aby mógł on pobierać i pracować z fragmentami takimi jak
<stdin> | parallel --pipe --block <block size> -k <task> > output.txt
gdzie <stdin>
może pochodzić z czegoś takiego jak cat <file>
.
Jako powtarzalny przykład naszym zadaniem będzie nl -n rz
. Weź dowolny plik, mój będzie data.bz2
i przekaż go do <stdin>
bzcat data.bz2 | nl | parallel --pipe --block 10M -k nl -n rz | gzip > ouptput.gz
Powyższy przykład pobiera <stdin>
z bzcat data.bz2 | nl
, gdzie output.gz
nl
tylko jako dowód koncepcji, że końcowy wynik wyjściowy.gz zostanie zapisany w kolejności, w jakiej został otrzymany. Następnie parallel
dzieli <stdin>
na kawałki o rozmiarze 10 MB i dla każdego kawałka przepuszcza je przez nl -n rz
gdzie po prostu dołącza odpowiednio uzasadnione liczby (zobacz nl --help
po dalsze szczegóły). Opcje --pipe
mówi parallel
aby podzielić <stdin>
na wiele zadań, a -- block
określa rozmiar bloków. Opcja -k
określa, że należy zachować porządek.
Twój końcowy wynik powinien wyglądać mniej więcej tak
000001 1 <data>
000002 2 <data>
000003 3 <data>
000004 4 <data>
000005 5 <data>
...
000587 552409 <data>
000588 552410 <data>
000589 552411 <data>
000590 552412 <data>
000591 552413 <data>
Mój oryginalny plik miał 552,413 linii. Pierwsza kolumna reprezentuje zadania równoległe, a druga kolumna reprezentuje oryginalną numerację linii, która została przekazana parallel
w porcjach. Powinieneś zauważyć, że kolejność w drugiej kolumnie (i reszcie pliku) jest zachowana.