Como eu mantenho as linhas com o número mais alto onde um padrão é correspondido?

2

Por exemplo, se meu arquivo se parece com isso:

string
string1
string2
string4
string800
value2
value3
value5
value10
something18
something20   

Eu quero que a saída seja

string800 
value10
something20

A palavra antes dos números poderia ser qualquer coisa, mas quando eu disse "onde um padrão é correspondido" eu quis dizer que eu quero manter o maior número onde a palavra antes do número é o mesmo, por exemplo, 800 é maior que 10 e 20, mas eu ainda quero manter os números contendo 10 e 20, quando a palavra antes é algo diferente do que era antes de 800, como no meu exemplo acima.

Eu preciso disso para trabalhar no OSX, então, por favor, evite os recursos que existem apenas nos utilitários GNU.

    
por DisplayName 19.12.2015 / 15:13

2 respostas

3

Eu não tenho um osx awk para experimentar, mas funciona no meu Linux gnu awk:

awk '
{ n = match($0, /[0-9]+ *$/);
  if(n){
    word = substr($0, 1, n - 1); num = 0 + substr($0, n);
    if(!(word in max) || max[word] < num) max[word] = num
  }
}
END{ for(word in max)print word max[word] } '

Em cada linha, procuramos o índice inicial na linha do padrão regexp que é um número com espaço em branco à direita opcional. Nós dividimos a linha nesse índice na parte da palavra e na parte do número. A string numérica é convertida em um número adicionando 0 a ela. Uma matriz associativa indexada pela palavra mantém o maior número.

    
por 19.12.2015 / 16:22
1

Se as linhas correspondentes a um determinado prefixo estiverem sempre agrupadas (ou seja, todos os stringNNN estão juntos, etc.), você pode usar awk, buffering lines, desde que tenham o mesmo prefixo, e então imprimir aquele com o maior sufixo.

awk '{
    match($0, /[0-9]*/);
    current_prefix = substr($0, 1, RSTART);
    current_number = substr($0, RSTART, RLENGTH);
    if (current_prefix == previous_prefix) {
        if (current_number > max_number) max_number = current_number;
    } else {
        if (NR != 1) print previous_prefix max_number;
        previous_prefix = current_prefix;
        max_number = current_number;
    }
}
END { if (NR != 1) print previous_prefix max_number; }'

Se as linhas correspondentes a um determinado prefixo não estiverem sempre agrupadas (por exemplo, você pode ter foo1 bar1 foo2 ), poderá classificar o arquivo primeiro.

    
por 20.12.2015 / 00:33