Mesclar registros dependendo de colunas comuns e especificar os valores que são incomuns na última coluna, separados por vírgula

Mesclar registros dependendo de colunas comuns e especificar os valores que são incomuns na última coluna, separados por vírgula

Preciso mesclar registros dependendo das três primeiras colunas comuns e colocar os valores incomuns na última coluna separados por vírgula. Eu tenho um requisito para fazer o seguinte-

Arquivo de entrada :

HWF CommonDomain  javatools       AdminServer
ABC CommonDomain  resourcebundle  AdminServer
HWF CommonDomain  stringeditor    AdminServer
ABC CommonDomain  resourcebundle  HelpPortalServer_1
HWF CommonDomain  stringeditor    HelpPortalServer_1 
HWF CommonDomain  javatools       HelpPortalServer_1

Resultado esperado:

ABC CommonDomain resourcebundle   AdminServer,HelpPortalServer_1
HWF CommonDomain javatools       AdminServer,IHelpPortalServer_1 
HWF CommonDomain stringeditor   AdminServer,HelpPortalServer_1 

Responder1

Obrigado por atualizar a pergunta, 100% melhor.

Você não mencionou se os valores que você chama de valores "incomuns" deveriam ser duplicados na saída, presumo que não.

Este script deve ser executado em todas as versões do awk. Sem extensões GNU,testado com gawk --traditional. Adicionei dados de entrada extras para testar mais condições. Isso lida com registros duplicados na entrada. O maior problema que prevejo seriam vírgulas na entrada, o script funcionará conforme especificado, mas o arquivo de saída pode parecer ter campos vazios, etc.

Descrição do código:

A recsmatriz é indexada pela concatenação dos três primeiros campos. (As matrizes awksão indexadas por strings.) Cada elemento da matriz contém o que você chama de campos "incomuns" separados por vírgulas.

Para cada linha de entrada: keycontém os três primeiros campos. O forloop percorre os campos restantes. A ifinstrução verifica se o campo ainda não foi armazenado para esta chave. Caso contrário, o campo será adicionado ao final do registro, precedido por um espaço ou vírgula, conforme apropriado.

No final da entrada ( ENDtag): Percorra as chaves até o array recs, imprimindo a chave e os dados nela contidos.

#!/bin/sh

awk '
    {
        key = $1 " " $2 " " $3;
        for (i = 4; i <= NF; i++) {
            if (recs[key] !~ "(^|,)"$i"(,|$)") {
                recs[key] = recs[key] (recs[key] ? "," : "") $i
            }
        }
    }
    END {
        for (key in recs) {
            print key " " recs[key]
        }
    }
' <<EOF
HWF CommonDomain  javatools       AdminServer
HWF CommonDomain  javatools       AdminServer2
HWF CommonDomain  javatools       3AdminServer
HWF CommonDomain  javatools       AdminServer
HWF CommonDomain  javatools       AdminServer
ABC CommonDomain  resourcebundle  AdminServer
ABC CommonDomain  resourcebundle  AdminServer
ABC CommonDomain  resourcebundle  AdminServer2
ABC CommonDomain  resourcebundle  3AdminServer
HWF CommonDomain  stringeditor    AdminServer2
HWF CommonDomain  stringeditor    3AdminServer
ABC CommonDomain  resourcebundle  HelpPortalServer
HWF CommonDomain  stringeditor    HelpPortalServer_1 
HWF CommonDomain  javatools       HelpPortalServer_1
HWF CommonDomain  javatools       HelpPortalServer_2
HWF CommonDomain  javatools       3_HelpPortalServer_2
HWF CommonDomain  stringeditor    HelpPortalServer 
HWF CommonDomain  javatools       HelpPortalServer_1
HWF CommonDomain  javatools       HelpPortalServer_2
HWF CommonDomain  javatools       3_HelpPortalServer
EOF

Saída:

HWF CommonDomain stringeditor AdminServer,HelpPortalServer_1
HWF CommonDomain javatools AdminServer,AdminServer2,3AdminServer,HelpPortalServer_1,HelpPortalServer_2,3_HelpPortalServer_2
ABC CommonDomain resourcebundle AdminServer,HelpPortalServer_1

informação relacionada