Otimize o shell e o script awk

0

Estou usando uma combinação de um shell script, awk script e um comando find para executar várias substituições de texto em centenas de arquivos. Os tamanhos dos arquivos variam entre algumas centenas de bytes e 20 kbytes.

Estou procurando uma maneira de acelerar esse script.

Estou usando o cygwin.

O script de shell -

#!/bin/bash

if [ $# = 0 ]; then
 echo "Argument expected"
 exit 1
fi



while [ $# -ge 1 ]
do
   if [ ! -f $1 ]; then
     echo "No such file as $1"
     exit 1
   fi


  awk -f ~/scripts/parse.awk $1  > ${1}.$$

   if [ $? != 0 ]; then
      echo "Something went wrong with the script"
     rm ${1}.$$
      exit 1
   fi
mv ${1}.$$ $1
shift
done

O script awk (simplificado) -

#! /usr/bin/awk -f

/HHH.Web/{
    if ( index($0,"Email") == 0)  {
        sub(/HHH.Web/,"HHH.Web.Email");
    }
    printf("%s\r\n",$0); 
    next;
}

A linha de comando

find .  -type f  | xargs ~/scripts/run_parser.sh
    
por bryan 16.02.2011 / 22:46

3 respostas

0

Isso vai recapitular todas as minhas centenas de arquivos em menos de 10 segundos. Anteriormente, levava 15 minutos.

find .  -type f | xargs awk -f ~/scripts/awkv2/parse.awk 

O script awk (simplificado) -

/HHH.Web/{
    if ( index($0,"Email") == 0)  {
        sub(/HHH.Web/,"HHH.Web.Email");
    }
    printf("%s\r\n",$0);  > FILENAME
    next;
}

MAS , se o arquivo de entrada for maior que 64kb, o arquivo de saída será truncado para aproximadamente 64kb.

Alguma ideia do porquê?

    
por 18.02.2011 / 01:14
0

1) existe um erro no seu tratamento de erros. Se um único xargs pass passar por um grupo de arquivos e um arquivo explodir, nenhum dos outros últimos arquivos será processado. por exemplo. se

~/scripts/run_parser.sh file1 file2 file3 file4

é executado, e o arquivo2 explode no awk, o arquivo1 é executado, mas nenhum arquivo2, arquivo3 ou arquivo4 será executado. Sugiro usar continue em vez de exit 1 .

2) Você está usando o Cygwin, você vai ser um pouco lento por causa da emulação, não pode ser ajudado. Será mais rápido no Linux usando as mesmas ferramentas.

3) Se você pode hackear algum perl, sugiro ver o que perl -p -i pode fazer. A sintaxe do Perl não é muito mais cabeluda que o awk, e você teria uma instanciação do perl contra várias do awk.

A menos que isso seja muito lento, eu talvez inclua problemas de emulação. Diferente do perl -p hack para superar alguns fork extra / executivos do awk, eu não acho que haja uma bala de prata em algum lugar.

    
por 16.02.2011 / 23:36
0

É o tamanho do buffer que está lendo um arquivo, e mais para apontar, você está sobrescrevendo o seu FILENAME original. Uma solução é usar

outFile= FILENAME ".fix"
printf("%s\r\n",$0);  > outFile

e ter um passe separado para

mv ${fileName}.fix ${fileName} 

no bash

Eu também concordo com Rich que a emulação do Cygwin faz com que seja mais lento. Além do Linux, dependendo da tolerância de nossa organização para o software opensource não-Gnu, você pode tentar o UWIN (Unix para Windows) de David Korn em link veja também o link .

Boa sorte

    
por 18.02.2011 / 17:41