Compare dois arquivos csv e adicione o valor usando awk [closed]

1

Eu tenho dois arquivos da seguinte forma: file1.csv

+------------+----------+--------+---------+
| Account_ID | Asset_ID | LOT_ID | FLAG_F1 |
+------------+----------+--------+---------+
|      10000 |    20000 |  30000 | Y       |
|      10001 |    20001 |  30001 | N       |
|      10002 |    20002 |  30002 | Y       |
|      10003 |    20003 |  30003 | N       |
|      10004 |    20004 |  30004 | Y       |
|      10005 |    20005 |  30005 | N       |
|      10006 |    20006 |  30006 | Y       |
+------------+----------+--------+---------+

file2.csv

   +------------+----------+--------+---------+-----+-----+
| Account_ID | Asset_ID | LOT_ID | FLAG_F2 | XYZ | ABC |
+------------+----------+--------+---------+-----+-----+
|      10000 |    20000 |  30000 | Y       | XYZ | ABC |
|      10001 |    20001 |  30001 | Y       | XYZ | ABC |
|      10002 |    20002 |  30002 | Y       | XYZ | ABC |
|      10003 |    20003 |  30003 | Y       | XYZ | ABC |
|      10004 |    20004 |  30004 | Y       | XYZ | ABC |
|      10005 |    20005 |  30005 | Y       | XYZ | ABC |
|      10006 |    20006 |  30006 | Y       | XYZ | ABC |
|      10006 |    20006 |  30006 | Y       | XYZ | ABC |
|      10006 |    20006 |  30006 | Y       | XYZ | ABC |
+------------+----------+--------+---------+-----+-----+

Estou tentando obter a seguinte saída :

    +------------+----------+--------+---------+-----+-----+---------+
| Account_ID | Asset_ID | LOT_ID | FLAG_F2 | XYZ | ABC | FLAG_F1 |
+------------+----------+--------+---------+-----+-----+---------+
|      10000 |    20000 |  30000 | Y       | XYZ | ABC | Y       |
|      10001 |    20001 |  30001 | Y       | XYZ | ABC | N       |
|      10002 |    20002 |  30002 | Y       | XYZ | ABC | Y       |
|      10003 |    20003 |  30003 | Y       | XYZ | ABC | N       |
|      10004 |    20004 |  30004 | Y       | XYZ | ABC | Y       |
|      10005 |    20005 |  30005 | Y       | XYZ | ABC | N       |
|      10006 |    20006 |  30006 | Y       | XYZ | ABC | Y       |
|      10006 |    20006 |  30006 | Y       | XYZ | ABC | Y       |
|      10007 |    20007 |  30006 | Y       | XYZ | ABC |         |
|      10006 |    20003 |  30006 | Y       | XYZ | ABC |         |
+------------+----------+--------+---------+-----+-----+---------+

Na saída acima, estou adicionando FLAG_F1 de file1.csv na file2.csv na condição de Account_ID,Asset_ID, e LOT_ID valores iguais em file1.csv e file2.csv . Se a condição falhar, pode ficar em branco.

Eu tentei o seguinte código, que é usado pelo dois arquivos .csv compare usando o awk

awk -F',' '
    FNR == NR {
        if (FNR == 1) {next}
        a[$1] = $2;
        b[$1] = $3;
        next;
    }
    {
        if (FNR == 1) {print;next}
        if (a[$1] == $2) {
            print $1,$2,$3,b[$1];
        }
        else {
            print $1,a[$1],b[$1],b[$1];
        }
    }
  ' OFS=',' file1.csv file2.csv

É melhor se alguém me explicar o código acima, linha por linha.

    
por Premraj 19.02.2015 / 14:54

2 respostas

2

Isso é muito mais simples que a questão vinculada. Tudo que você precisa é:

awk -F, -v OFS=, 'NR==FNR{a[$1$2$3]=$4; next}{print $0,a[$1$2$3]}' file1 file2

Explicação

  • -F, : define o separador do campo de entrada para uma vírgula.
  • -v OFS=, : define o separador do campo de saída para uma vírgula. Isso é útil para imprimir a saída separada por vírgulas por padrão.
  • NR==FNR : NR é o número da linha atual, FNR é o número da linha do arquivo atual. Os dois serão idênticos apenas enquanto o primeiro arquivo estiver sendo lido.
  • a[$1$2$3]=$4; next : se este for o primeiro arquivo (veja acima), salve o quarto campo em uma matriz cuja chave é o primeiro, segundo e terceiro campos concatenados.
  • print $0,a[$1$2$3] : imprime a linha atual ( $0 ) e o valor na matriz a associada aos três primeiros campos. Este é o quarto campo correspondente do primeiro arquivo.
por 19.02.2015 / 16:22
2
awk -F',' ' # start awk and use comma as a field separator
    FNR == NR { # if processed so far number of rows in current file if equal to overall processed number of rows do things in block {} 
        if (FNR == 1) {next} # if it is first row then continue (skip to next row)
        a[$1] = $2; # create an array indexed with first field, with value of second field
        b[$1] = $3; # another array
        next; # go to next row
    } # end of block executed only for first file
    { # beginning of block which will be executed without any initial conditions
        if (FNR == 1) {print;next} # if first row of file then print it and go to next one
        if (a[$1] == $2) { # if array value which correspond to field first is equal to second field do something (array 'a' has been set in first file, and now we input index to file from second file knowing that first fields of those files are the same)
            print $1,$2,$3,b[$1]; # print field 1-3 and array b[$1]
        }
        else { # if array is not equal
            print $1,a[$1],b[$1],b[$1]; # print stuff
        }
    }
  ' OFS=',' file1.csv file2.csv # OFS means output field separator, so we want to have comma in result too.
    
por 19.02.2015 / 15:10