Maneira eficiente de pesquisar matriz no arquivo de texto pelo AWK

1

Eu tenho um array SPLNO com aproximadamente 10k numbers.Now eu quero procurar o número de assinante do arquivo MDN.TXT (contendo aproximadamente 1,5 lac registro) da matriz.se número do assinante encontrado na matriz ele irá executar abaixo operation.my O problema é que ele está demorando mais, porque, para um número, ele busca uma matriz inteira de registros de 10k. portanto, para 1,5 registros lac ele está dando voltas (1,5lac * 10K). por favor, sugira maneiras eficientes.

Exemplo SPLNO.TXT:

918542054921 | 30 | 1 | 2 | 918542144944 | 12 | 1 | 2
918542155955 | 12 | 1 | 2
918542166966 | 12 | 1 | 2
918542255955 | 12 | 1 | 2
918542355955 | 12 | 1 | 2
918542455955 | 12 | 1 | 2
918542555955 | 12 | 1 | 2
918542955955 | 12 | 1 | 2

Exemplo de MDN.TXT:

8542166966
8542355955
8542555955

awk -F"|"  'FNR==1 { ++counter}
counter==1 {SPLNOPULSE[$1]=$4;SPLNOAMT[$1]=$3;SPLNOMAXLEN[$1]=$2;next}
{
for ( mdn in SPLNOMAXLEN)
        {
         if ( ($1 ~ "^"mdn && length($1) <=SPLNOMAXLEN[mdn]) || ("91"$1 ~ "^"mdn && length("91"$1) <=SPLNOMAXLEN[mdn]) )
              {                              
                print found
               }
         else
                print not found
        }                             
 } ' SPLNO.TXT MDN.TXT
    
por user3548033 19.10.2015 / 08:20

2 respostas

0

Aqui está uma abordagem, usando perl .

#!/usr/bin/perl
# read the subscribers
open(A,"<","SPLNO.TXT");
while(<A>) {
 chomp;
 @a=split(/\|/,$_);
 $splnopulse{$a[0]}=$3;
 $splnoamt{$a[0]}=$2;
 $splnomaxlen{$a[0]}=$1;
}
close A;

# read the mdn, looking for matches
open(B,"<","MDN.TXT");
while(<B>) {
 chomp;
 @b=split(/\|/,$_);
 foreach $mdn (keys %splnomaxlen) {
  if($mdn eq $b[0] || "$mdn" eq "91" . $b[0]) {
   print "found\n";
  } else {
   print "not found\n";
  }
 }
}
close B;
    
por 20.10.2015 / 18:24
0

O algoritmo de pesquisa de todo o arquivo 2 para cada linha no arquivo 1 tem um desempenho de tempo de m * n . Onde m é a contagem de linhas de arquivo 2 e n é a contagem de linhas de arquivo 1. Isso se torna muito lento rapidamente.
A solução é primeiro classificar cada arquivo (que é um n * log (n) tempo) e, em seguida, comparar as linhas entre os dois arquivos como este:

  1. Crie i = 1 (número da linha do arquivo 1) e j = 1 (número da linha do arquivo 2).
  2. Comparar a=(file 1)[line i] com b=(file 2)[line j] .
  3. if a<b; , em seguida, incrementa i, retorna para 2 (verifique o final do arquivo 1).
  4. if a>b; , em seguida, incrementa j, retorna para 2 (verifique o final do arquivo 2).
  5. if a=b; isto é uma correspondência, imprima, incremente i.

Isso tem um tempo de execução de apenas: n + m (o tempo para ler todas as linhas).

Todo o processo, então, tem um tempo de execução de: n*log(n) + m*log(m) + n + m .
Que tem um O (n) de: n * log(n) para n > m .

a ordenação é fácil de fazer, basta usar o comando sort para cada arquivo:

sort -t '|' -k 1 file01.csv > file01-sorted.csv

Em seguida, execute o procedimento acima no awk.

Editar: Acontece que se todos os 10k números de SPLNO são únicos (sem repetições). E o MDN.TXT também possui registros exclusivos. Em seguida, concatenar os dois arquivos e pesquisar por valores repetidos também fornecerá uma solução. Isso funciona para igualdade simples. Correspondências de regex quebrarão essa ideia na maioria dos casos.

    
por 21.10.2015 / 23:49