Buscar..
Introducción
Los trabajos en GNU Linux pueden ser paralelos utilizando GNU en paralelo. Un trabajo puede ser un solo comando o un pequeño script que debe ejecutarse para cada una de las líneas en la entrada. La entrada típica es una lista de archivos, una lista de hosts, una lista de usuarios, una lista de URL o una lista de tablas. Un trabajo también puede ser un comando que se lee desde una canalización.
Sintaxis
- paralelo [opciones] [comando [argumentos]] <list_of_arguments>
Parámetros
Opción | Descripción |
---|---|
-jn | Ejecutar n trabajos en paralelo |
-k | Mantener el mismo orden |
-X | Múltiples argumentos con reemplazo de contexto |
--colsep regexp | Entrada dividida en expresiones regulares para reemplazos posicionales |
{} {.} {/} {/.} {#} | Cuerdas de repuesto |
{3} {3.} {3/} {3/.} | Cuerdas de reemplazo posicional |
-S sshlogin | Example: [email protected] |
--trc {}.bar | Taquigrafía para --transfer --return {} .bar --cleanup |
--onall | Ejecuta el comando dado con argumento en todos los sshlogins |
--nonall | Ejecute el comando dado sin argumentos en todos los sshlogins |
--pipe | Dividir stdin (entrada estándar) a múltiples trabajos. |
--recend str | Registre el separador final para --pipe. |
--recstart str | Registre el separador de inicio para --pipe. |
Paralelizar tareas repetitivas en la lista de archivos
Muchos trabajos repetitivos se pueden realizar de manera más eficiente si utiliza más recursos de su computadora (es decir, CPU y RAM). A continuación se muestra un ejemplo de ejecución de varios trabajos en paralelo.
Supongamos que tiene una < list of files >
, digamos el resultado de ls
. Además, deje que estos archivos estén comprimidos en bz2 y el siguiente orden de tareas debe operarse en ellos.
- Descomprima los archivos bz2 usando
bzcat
para stdout - Líneas de grep (p. Ej., Filtro) con palabras clave específicas que utilizan
grep <some key word>
- Canalice la salida para que se concatene en un solo archivo comprimido con
gzip
usandogzip
Ejecutar esto usando un bucle while puede verse así
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"
Usando GNU Parallel, podemos ejecutar 3 trabajos paralelos a la vez simplemente haciendo
parallel -j 3 "bzcat {} | grep puppies" ::: $( cat filelist.txt ) | gzip > output.gz
Este comando es simple, conciso y más eficiente cuando la cantidad de archivos y el tamaño de los archivos es grande. Los trabajos se inician en parallel
, la opción -j 3
inicia 3 trabajos en paralelo y la entrada a los trabajos en paralelo se realiza mediante :::
. La salida finalmente se canaliza a gzip > output.gz
Paralelizar STDIN
Ahora, imaginemos que tenemos 1 archivo grande (por ejemplo, 30 GB) que se debe convertir, línea por línea. Digamos que tenemos un script, convert.sh
, que hace esto <task>
. Podemos canalizar el contenido de este archivo a stdin para que lo tomemos en paralelo y lo trabajemos en fragmentos como:
<stdin> | parallel --pipe --block <block size> -k <task> > output.txt
donde <stdin>
puede originarse desde algo como cat <file>
.
Como ejemplo reproducible, nuestra tarea será nl -n rz
. Toma cualquier archivo, el mío será data.bz2
, y data.bz2
a <stdin>
bzcat data.bz2 | nl | parallel --pipe --block 10M -k nl -n rz | gzip > ouptput.gz
El ejemplo anterior toma <stdin>
de bzcat data.bz2 | nl
, donde output.gz
nl
solo como prueba de concepto de que la salida final output.gz
se guardará en el orden en que se recibió. Luego, el parallel
divide el <stdin>
en trozos de tamaño 10 MB, y por cada fragmento lo pasa a través de nl -n rz
donde solo agrega un número justificado (consulte nl --help
para obtener más detalles). Las opciones --pipe
dice en parallel
a dividir <stdin>
en varios trabajos y -- block
especifica el tamaño de los bloques. La opción -k
especifica que se debe mantener el orden.
Tu salida final debería verse como
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>
Mi archivo original tenía 552,413 líneas. La primera columna representa los trabajos paralelos, y la segunda columna representa la numeración de línea original que se pasó a parallel
en partes. Debe observar que el orden en la segunda columna (y el resto del archivo) se mantiene.