acelera o script bash iniciando várias instâncias em um loop for

4

Eu tenho este script:

 for i in 'find ! -newermt "2016-02-13" -name "*svgz"'; do
  inkscape --verb FitCanvasToDrawing --verb FileSave --verb FileClose ${i} --verb FileQuit
done

que espera que o inkscape termine seu trabalho e, em seguida, o reinicia com o próximo arquivo. Eu gostaria de ter quatro instâncias do inkscape em paralelo para acelerar o processo (tenho ~ 5.000 arquivos para processar). Isso é possível, e se sim, como? Obrigado antecipadamente!

    
por HinzundKunz 29.02.2016 / 12:38

3 respostas

2

Experimente o GNU Parallel.

sudo aptitude install parallel

Eu não uso há algum tempo, mas sua linha de comando deve ser semelhante à abaixo:

find ! -newermt "2016-02-13" -name "*svgz" | \
  parallel -j4 \
    inkscape \
    --verb FitCanvasToDrawing \
    --verb FileSave \
    --verb FileClose {} \
    --verb FileQuit

em que 4 é o número de processos que você deseja executar a qualquer momento.

    
por Marcin Kaminski 29.02.2016 / 13:29
1

Você pode usar o GNU paralelo, como explicado aqui, para uma pergunta muito semelhante que também envolve o inkscape: link

Outro truque simples que usei recentemente é o seguinte:

  1. Crie um shellscript "process.sh" processando um único arquivo passado como argumento para isso.
  2. Armazene o resultado do comando find em um arquivo de texto

  3. Divida o arquivo usando o comando "split" em quantos trabalhos desejar para rodar em paralelo.

  4. Executa várias instâncias de process.sh passando argumentos para ele através dos arquivos divididos gerados e xargs.

por KIAaze 29.02.2016 / 13:34
0

Veja como eu abordaria isso. Como eu não tenho os mesmos arquivos, o código de exemplo abaixo tem como objetivo abrir 4 arquivos de texto com gedit .

Como isso funciona? Bem, primeiro encontramos os arquivos no local codificado onde os arquivos podem ser armazenados ( FILEPATH variable). Em seguida, passamos para while read structure. Observe o uso de -print0 e IFS= read -d'' . Isso é muito comum na programação bash para eliminar nomes de arquivos problemáticos que contêm espaços, caracteres não imprimíveis, etc.

Cada gedit file & chama gedit sendo desanexado do script com & . Isso faz com que o loop continue sem parar.

O que faz o loop parar é a variável COUNT. Uma vez que contamos de 0 a algum número divisível por 4, a variável MOD , que é calculada a partir do operador de módulo, se tornará 0. Agora o shell aguardará um popup (que é zenity ) confirmar a geração de mais 4 janelas . Dessa forma nós contamos 4 vezes, resetar variável, continuar.

A única desvantagem aqui é que find não classifica os arquivos, portanto eles não estarão necessariamente na ordem nomeada. Se a ordem é importante, o código precisará de instruções adicionais. Caso contrário, isso é suficiente.

#!/bin/bash

FILEPATH="/home/xieerqi/MYTEXTFILES"
COUNT=0

find $FILEPATH -type f -name "*.txt" -print0 | \
while IFS= read -d ''  FILE;
do
    gedit $FILE & 
    COUNT=$(( $COUNT+1 ))
    MOD=$(( $COUNT % 4 ))

    if [ $MOD -eq 0   ]
    then 
        zenity --question --text "Open 4 more files?"  || exit
    fi
done
    
por Sergiy Kolodyazhnyy 29.02.2016 / 16:28