processando vários arquivos com problema awk

0

Eu tenho os arquivos de entrada com campos separados por dois-pontos:

main:

one:111:222:333
fiv:333:222:333
two:123:234:500

arquivo1:

one:111:222:333
two:123:234:501

arquivo2:

one:111:222:333
thr:-:234:232
fiv:999:500:232

Graças a dicas no link eu tenho um código awk modificado:

$ awk -F':' -vf=main 'FILENAME==f{m=$0};FILENAME!=f&&$2~/[0-9]+/{if ($2~/[0-9]+/&&(!($1 in a) || $3 > a[$1])) { a[$1] = $3; b[$1] = $0 } next;}{if (($1 in a) && (a[$1] > $3)){ print b[$1]":updated:"m; delete b[$1] } else print; }' file* main
thr:-:234:232
one:111:222:333
fiv:999:500:232:updated:fiv:333:222:333
two:123:234:500

Por que imprime também a linha thr:-:234:232 ? Como thr não ocorre no arquivo principal, ele deve ser ignorado para qualquer atualização nele. Atualizadas devem ser apenas essas linhas baseando-se na 1ª coluna, que existe no arquivo principal e as linhas correspondentes com a 1ª coluna existem no arquivo1 ou no arquivo2 e têm um valor maior na 3ª coluna.

Por que $2~/[0-9]+/ não funciona aqui?

Atualização: Ainda não entendi, por favor dê uma olhada:

quando modifico o arquivo principal do teste para:

one:111:222:333 fiv:333:222:333 two:123:234:500 ten.233:422:452

E execute este comando do awk:

$ awk -F':' -vf=main 'FILENAME==f{m=$0};FILENAME!=f&&$2~/[0-9]+/{if ($2~/[0-9]+/&&(!($1 in a) || $3 > a[$1])) { a[$1] = $3; b[$1] = $0 } next;}{if (($1 in a) && (a[$1] > $3)){ print b[$1]":updated:"m; delete b[$1] } else print; }' file* main
thr:-:234:232
one:111:222:333
fiv:999:500:232:updated:fiv:333:222:333
two:123:234:500
ten.233:422:452

Portanto, a saída está errada por causa da linha thr que não deve estar na saída, pois thr não está em main file

Eu modifiquei o comando adicionando condição adicional else if($1 in a) {print}; mas então não imprime linha começando com "dez" no arquivo principal:

$ awk -F':' -vf=main 'FILENAME==f{m=$0};FILENAME!=f&&$2~/[0-9]+/{if ($2~/[0-9]+/&&(!($1 in a) || $3 > a[$1])) { a[$1] = $3; b[$1] = $0 } next;}{if (($1 in a) && (a[$1] > $3)){ print b[$1]":updated:"m; delete b[$1] } else if($1 in a) {print}; }' file* main
one:111:222:333
fiv:999:500:232:updated:fiv:333:222:333
two:123:234:500

Eu aprecio muito qualquer ajuda.

Awk é realmente muito legal, infelizmente eu não sendo um programador não consigo descobrir sozinho.

    
por DonJ 13.04.2018 / 23:03

1 resposta

3

Porque você tem next no bloco com a condição FILENAME != f && $2 ~ /[0-9]+/ . Essa linha thr não atende a essa condição, portanto, ela cai no bloco "todas as linhas". Lá, $ 1 não está em a , então o bloco else é inserido e a linha é impressa.

Tenho certeza de que você teria sido capaz de descobrir isso sozinho, se você usou um recuo sensato para ver o seu programa:

awk -F':' -vf=main '
    FILENAME == f {m = $0}
    FILENAME != f && $2 ~ /[0-9]+/ {
        if ($2 ~ /[0-9]+/ && (!($1 in a) || $3 > a[$1])) { 
            a[$1] = $3
            b[$1] = $0 
        } 
        next
    }
    {
        if (($1 in a) && (a[$1] > $3)) { 
            print b[$1]":updated:"m
            delete b[$1] 
        } else 
            print
    }
' file* main
    
por 14.04.2018 / 02:19

Tags