Agrupando o valor múltiplo correspondente à chave única no arquivo csv usando o AWK

1

Ao agrupar os valores correspondentes à chave única, testei isso em um arquivo no formato csv com mais de dois campos, como:

Keyobject,FieldName,Fieldvalue
1,are you sleeping,yes
1,country of meeting,USA 
2,are you sleeping,' '
2,country of meeting,' '
3,are you sleeping,yes
3,country of meeting,CHINA
4,are you sleeping,yes
4,country of meeting,ITALY

Resultado esperado:

Keyobject,Are you sleeping,country of meeting
1,yes,USA
2, ,
3,yes,CHINA
4,no,ITALY.

Por favor, forneça a ideia aproximada ou qualquer script.

    
por Dinesh Boora 03.10.2018 / 20:50

4 respostas

1

awk -F, '
    NR > 1 {ids[$1]; keys[$2]; value[$1,$2] = $3}
    END { 
        printf "Keyobject"
        for (k in keys)
            printf ",%s", k
        print ""

        for (id in ids) {
            printf id
            for (k in keys)
                printf ",%s", value[id,k]
            print ""
        }
    }
' file
    
por 03.10.2018 / 23:30
0

Tente também

awk -F, -v OFS="," '
NR == 1                 {HD      = "Keyobject,are you sleeping,country of meeting"
                         for (MX=n=split (HD, HDArr, OFS); n>0; n--) SRCH[HDArr[n]]
                         print HD
                         next
                        }


$2 in SRCH              {RES[$2] = $3
                         RES[HDArr[1]] = $1
                        }

NR%2                    {for (i=1; i<=MX; i++) printf "%s%s", RES[HDArr[i]], (i == MX)?ORS:OFS
                         split ("", RES)
                        }

' file
Keyobject,are you sleeping,country of meeting
1,yes,USA 
2,' ',' '
3,yes,CHINA
4,yes,ITALY

Ao ler a linha 1, o cabeçalho e uma matriz de pesquisa indexada pelos elementos de cabeçalho são criados e o cabeçalho é impresso. Nas linhas seguintes, a matriz de resultados indexada por $ 2 recebe $ 3 e é redundante para a cadeia de índice "Keyobject". Para cada segunda linha, o resultado é impresso e a matriz de resultados é excluída.

    
por 03.10.2018 / 23:16
0
awk <file -v IV="' '" -v OV=" " -F, '
        $1+0 {
                b = $2 == IV ? OV : $2
                a[$1,$2] = $3 == IV ? OV : $3
                if($1 > max) max = $1; t[$2]++;
        }
        END{
                ORS = ""
                print "Keyobject"
                for(k in t) print FS k
                print RS
                for(i = 1; i <= max; i++){
                        print i
                        for(k in t)
                                print FS (i SUBSEP k in a ? a[i,k] : OV)
                        print RS
                }
        }
'

Ajuste as variáveis IV e OV para o que deve ser um campo vazio na entrada e na saída, respectivamente.

    
por 03.10.2018 / 23:01
0

Digamos que seu arquivo csv seja chamado de "list.csv". Eu faria assim:

#!/bin/bash
echo -e "Keyobject","Are you sleeping ", " Country of meeting"   # create new header
cat list.csv | sed 1,1d | awk -F, 'NF>1{print $NF}' | paste -d', ' - - | sed 's/ /,/' | nl


 1  yes,USA 
 2  ' ', ' '
 3  yes,CHINA
 4  yes,ITALY

Explicação:

sed 1,1d # This command excludes the original header in list.csv
awk -F, 'NF>1{print $NF}' # This command reads the last word in each row
paste -d', ' - -  # This command paste the words beside each other 
sed 's/ /,/'  # This command replaces blank spaces with commas
nl # This command adds numbering to the rows in the final output

No entanto, esta solução assume que as linhas no arquivo csv original são organizadas conforme apresentado no exemplo acima.

    
por 03.10.2018 / 22:49

Tags