Uma maneira mais eficiente de processar uma grande quantidade de arquivos (300k +) para coletar resultados?

3

Eu tenho um arquivo chamado fields.txt e contendo L=300k+ linhas que se parecem com:

field1 field2 field3
field1 field2 field3
field1 field2 field3
... 
field1 field2 field3

Na mesma pasta, tenho N arquivos contendo apenas uma sequência (vamos identificá-la s(n) ) e nomeada res-0-n-0 , com n em qualquer lugar entre 0 e L . No entanto N < L .

Gerei o arquivo res_numbers_sorted.tmp contendo a lista numericamente classificada do n acima mencionado com o comando (não tenho certeza se é o mais eficiente, mas é razoavelmente rápido e preciso que isso seja classificado para outros propósitos)

find -maxdepth 1 -type f -name "res-0-*" | sort -t'-' -k3 -n | awk -F'-' '{print $3}'>| res_numbers_sorted.tmp

O arquivo res_numbers_sorted.tmp se parece com:

0
1
8
... 
299963

Finalmente, o que eu quero é um arquivo chamado results.txt que gostaria de:

field1 field2 field3 s(0)
field1 field2 field3 s(1)
field1 field2 field3
...
field1 field2 field3 s(299963) 
...
field1 field2 field3

onde novamente s(n) é a string contida no n-ésimores-0-n-0.

Eu consegui o que quero primeiro em cp fields.txt resutls.txt e depois com o seguinte while loop:

while IFS='' read -r line; do 
     #storing the content of the file in a variable
     res=$(<res-0-"$line"-0)     
     # this is needed in order to take into account that sed addresses the first line of a file with the number 1 whereas the file list starts with 0
     real_line=$(( line + 1 ))     
     sed -i "${real_line}s/.$/ ${res}/" field.txt
done < res_numbers_sorted.tmp

No entanto, isso é muito lento e preciso executá-lo várias vezes. Eu suspeito que talvez sed não seja a ferramenta certa para esse trabalho.

    
por woland 19.04.2018 / 11:07

2 respostas

2

Se eu entendi corretamente, você tem um arquivo fields.txt com muitas linhas. Você tem vários arquivos res-0-n-0 . E, para cada linha em fields.txt , copie-as em results.txt , se existir, o conteúdo do arquivo res-0-<line_number> .

Acho que você pode simplesmente ler o arquivo fields.txt linha por linha e fazer eco da linha no results.txt com o conteúdo do arquivo res-0-<line_number> , se necessário.

Eu iria com algo assim:

#! /bin/sh

LINE_NUMBER=0
while read line;
do
  if [ -f "res-0-$LINE_NUMBER-0" ]
  then
    echo "$line $(cat res-0-$LINE_NUMBER-0)" >> result.txt
  else
    echo "$line" >> result.txt
  fi
  ((LINE_NUMBER++))
done < fields.txt
    
por 19.04.2018 / 11:51
2

Tente gerar um script sed e, em seguida, aplique-o apenas uma vez no arquivo field.txt :

while IFS='' read -r line; do
    res=$(<res-0-"$line"-0)
    real_line=$(( line + 1 ))
    prinft "%s" "${real_line}s/.$/ ${res}/" >> myscript.sed
done < res_numbers_sorted.tmp

e faça:

sed -i -f myscript.sed field.txt

Dessa forma, você só faz uma iteração sobre o arquivo grande. Avise-me se isso ajudar.

    
por 19.04.2018 / 11:40