Acelerar o processamento de texto

4

Eu tenho o seguinte script para processar um arquivo com alguns dados: Primeiro, o cabeçalho é impresso no arquivo de saída. Em seguida, 60000 linhas da entrada são escolhidas aleatoriamente e impressas na saída (a possibilidade de imprimir a mesma linha várias vezes é explicitamente desejada).

N = 60000
gawk '{if (NR < 37) print $0}' input > output
MAX=$(gawk 'END{print NR}' input)

for ((i=1; i<=$N; i++ ))
do

   declare $(gawk -v min=37 -v max=$MAX -v seed=$RANDOM 'BEGIN{srand(seed); print "x="int(min+rand()*(max-min+1))}')
   gawk -v l=$x 'NR>36 && NR==l {print $0}' input >> output

done

Eu agora que isso é muito ineficiente, então estou aberto a qualquer idéia de como melhorar o desempenho deste código, talvez seja possível evitar a abertura e o fechamento do arquivo de entrada o tempo todo?

Obrigado pelo seu tempo!

    
por quadrupoltensor 07.05.2018 / 15:30

1 resposta

14

Primeiro você deve extrair um cabeçalho de 36 linhas do arquivo chamado input , depois escolher 60000 linhas aleatórias do restante do arquivo com a possibilidade de escolher aleatoriamente a mesma linha várias vezes. Toda saída deve ir para o arquivo chamado output .

Usando shuf dos núcleutils GNU:

#!/bin/sh

# Fetch header (36 first lines)
head -n 36 <input >output

# Scramble the other lines and pick 60000 (allowing for repeated lines)
tail -n +37 <input | shuf -r -n 60000 >>output

Alternativamente:

( head -n 36 <input; tail -n +37 <input | shuf -r -n 60000 ) >output

Com GNU head , que deixa o fluxo do arquivo de entrada na posição após a última linha produzida, o que significa que shuf pode continuar onde head terminou de ler (isso pode não funcionar com alguns implementações não-GNU head ):

( head -n 36; shuf -r -n 60000 ) <input >output
    
por 07.05.2018 / 15:39