bash string manipulação velocidade vs. pipeline

1

Eu tenho um arquivo cheio de checksums e nomes de arquivos md5. Preciso realizar algum processamento em cada linha, então preciso saber:

  • Qual é a soma de verificação
  • Qual é o nome do arquivo

e aja de acordo. Ou seja, eu preciso sugar a soma de verificação para uma variável e, em seguida, o nome do arquivo. O nome do arquivo pode ter caracteres não ascii, mas não espero ver novas linhas. Parece assim:

05c00367e8914ca1be0964821d127977  ./.fseventsd/0000000000097aa1
cd9d4291f59a43c0e3d73ff60a337bb5  ./.fseventsd/00000000000fdfec
5d1280769e741e04622cfd852f33a138  ./.fseventsd/0000000000103197
8dda3534e5bbc0be1d15db2809123c50  ./.fseventsd/000000000017c9ca
(...etc., about 100,000 lines)

Tradicionalmente, posso realizar algo assim:

md5sum=$(echo $line | awk '{print $1}')
filename=$(echo $line | sed 's/[^ ]*  //')

Mas quanto mais rápido seria se eu fizesse isso:

md5sum=${line%%" "*}
filename=${line#*"  "}
    
por Mike S 13.07.2018 / 00:00

2 respostas

0

Sim, usando o comando interno bash, evita muitas chamadas do sistema. Especialmente quando há recursão.

Outro exemplo: devemos usar * contra $ (ls).

O Bash oferece algumas maneiras de fazer manipulações simples em strings (cortes e substituições). Mas não mais. Porque não é feito para isso. Exemplo: difícil validar a presença de um padrão em uma string sem um comando externo.

Programas externos são mais otimizados para suas tarefas (cat, sed, grep, awk, corte, classificação, ...)

    
por 13.07.2018 / 04:46
0

Eu testei definindo uma das variáveis. Executando este script duas vezes:

while read line; do
        md5sum=${line%%" "*}
        #md5sum=$(echo $line | awk '{print $1}')
        echo "SUM: $md5sum FILE:_$file"
done < manifest.Stuph.180620

primeiro com

md5sum=${line%%" "*}

e depois com

md5sum=$(echo $line | awk '{print $1}')

onde o arquivo "manifest.Stuph.180620" tem 100939 linhas (== aproximadamente 14MiB) deu os seguintes resultados:

Primeira execução (usando a manipulação de strings do bash)

real    0m4.750s
user    0m4.174s
sys     0m0.550s

Segunda execução (usando o pipeline)

real    10m54.255s
user    4m42.257s
sys     7m32.880s

Alguns (como eu) dirão que, se a velocidade é importante, então você não deveria estar mexendo no shell de qualquer maneira, mas às vezes você pode querer ser mais eficiente - não importa qual ambiente você esteja usando para o trabalho .

Observe que fazendo isso:

while read md5sum filename; do
    (...etc...)

é ainda mais eficiente do que fazer a atribuição de variável, mas não ao grau de eliminar a construção de substituição de comando / pipe / awk. A coisa que eu acho mais interessante é a diferença entre o desempenho integrado do bash e o uso de comandos externos. Eu serei mais diligente em aprender e usar as coisas sofisticadas!

    
por 13.07.2018 / 00:00

Tags