Une dois arquivos em dois campos comuns

5

Eu tenho dois arquivos

file1.txt

78Z|033333157|0000001|PERD1|2150421|D|0507020|3333333311
78Z|033333157|0000001|PERD0|2160208|A|1900460|3333333311
78Z|033333157|0000001|RSAB1|2150421|D|0507070|3333333311
78Z|033333157|0000001|RSAB0|2160208|A|1900460|3333333311
78Z|033333157|0000001|ANT37|2141023|D|1245260|3333333311
78Z|033333157|0000001|ANT36|2150422|D|1518490|3333333311
78Z|033333157|0000001|ANT28|2150321|D|0502090|3333333311
78Z|033333157|0000001|ANT27|2150122|D|0501450|3333333311
78Z|033333157|0000001|ANT26|2141222|D|1637460|3333333311
78Z|033333157|0000001|ANT10|2160208|A|1900460|3333333311
78Z|033333157|0000001|ABS10|2151221|D|1223390|3333333311
78Z|696931836|0000001|PERD0|2160203|A|1114450|2222222222
78Z|696931836|0000001|RSAB0|2160203|A|1114450|2222222222
78Z|696931836|0000001|ANT09|2160203|A|1114450|2222222222
78Z|010041586|0000001|PERD0|2160119|A|1835100|3333333333
78Z|010041586|0000001|RSAB0|2160119|A|1835100|3333333333
78Z|010041586|0000001|ANT33|2160119|A|1835100|3333333333
78Z|011512345|0000001|PERD0|2151213|A|1413550|4444444444
78Z|011512345|0000001|RSAB0|2151213|A|1413550|4444444444
78Z|011512345|0000001|ANT32|2160219|A|0319230|4444444444
78Z|011512345|0000001|ANT09|2160218|D|0319230|4444444444
78Z|011512345|0000001|ANT07|2150729|D|1508230|4444444444
78Z|011512345|0000001|ANT06|2141013|D|1208190|4444444444
78Z|011512345|0000001|ABB06|2131224|D|1857030|4444444444
78Z|012344052|0000001|PERD0|2160203|A|1219570|5555555555
78Z|012344052|0000001|ANT50|2160203|A|1219570|5555555555
78Z|099999999|0000001|PERD0|2151214|A|1512460|6666666666
78Z|099999999|0000001|RSAB0|2151214|A|1512460|6666666666
78Z|099999999|0000001|ANT32|2160219|A|0319000|6666666666
78Z|099999999|0000001|ANT09|2160218|D|0319000|6666666666
78Z|099999999|0000001|ABS10|2150615|D|0125350|6666666666

file2.txt

3333333311|ANT10
2222222222|ANT09
5555555555|ANT50
3333333333|ANT33
6666666666|ANT32
4444444444|ANT09

Eu preciso criar um novo arquivo com as linhas correspondidas pela quarta e oitava coluna do file1.txt com a segunda e a primeira coluna do file2.txt

O resultado deve ser (a ordem não é importante)

file3.txt

78Z|033333157|0000001|ANT10|2160208|A|1900460|3333333311
78Z|696931836|0000001|ANT09|2160203|A|1114450|2222222222
78Z|012344052|0000001|ANT50|2160203|A|1219570|5555555555
78Z|010041586|0000001|ANT33|2160119|A|1835100|3333333333
78Z|099999999|0000001|ANT32|2160219|A|0319000|6666666666
78Z|011512345|0000001|ANT09|2160218|D|0319230|4444444444
    
por Miguel Angel 22.02.2016 / 20:56

4 respostas

5
awk -F'|' 'NR==FNR{e[$2$1]=1;next};e[$4$8]' file2.txt file1.txt

Primeiro, leia arquivo2 e defina a matriz e[field2+field1] , em seguida, arquivo1 e imprima se e[field4+field8] estiver definido.

Ou transforme os campos:

awk -F'|' 'NR==FNR{e[$1$2]=1;next};e[$8$4]' file2.txt file1.txt
    
por 22.02.2016 / 22:15
4

A questão está marcada com , mas acho que vale a pena notar que você não tem para usar awk para fazer isso. Os coreutils têm um utilitário join que é útil para esse tipo de coisa, embora com seus dados seja um pouco complicado.

Eu vou assumir que seu shell é bash e GNU coreutils. Isso pode ser feito com outros tipos, mas provavelmente precisará de mais pré / pós-processamento de seus dados.

Sem mais delongas:

join -t"|" -14 -22 -o"$(echo 1.{1..8} 2.1)" \
  <(sort -t"|" -k4 file1.txt) \
  <(sort -t"|" -k2 file2.txt) \
  | grep -Po ".*([\d]+)(?=\|$)"

join recebe dois arquivos de entrada e os associa aos campos aprovados pelos parâmetros -1 e -2 . -t indica um separador de campo personalizado nos arquivos de entrada. join requer que os arquivos de entrada sejam classificados nos campos que estão sendo unidos, portanto, os dois arquivos de entrada são classificados nas substituições do processo antes de serem passados para join . O parâmetro -o especifica como os campos devem ser enviados. Por padrão, é o campo join, seguido pelos campos non-join do arquivo1, seguidos pelos campos non-join do arquivo2, portanto, precisamos especificar que queremos todos os campos do arquivo 1 em ordem, seguidos pelo campo 1 do arquivo 2.

Você também exige que a associação esteja no campo 8 do arquivo1 e no campo 1 do arquivo1. Isto é simplesmente implementado aqui, usando as linhas quando os campos de saída de junção 8 e 9 são os mesmos. Usar um lookahead de regexp com grep -Po nos permite fazer isso e efetivamente excluir o campo 9 para fornecer a saída necessária. A saída é:

78Z|696931836|0000001|ANT09|2160203|A|1114450|2222222222
78Z|011512345|0000001|ANT09|2160218|D|0319230|4444444444
78Z|033333157|0000001|ANT10|2160208|A|1900460|3333333311
78Z|099999999|0000001|ANT32|2160219|A|0319000|6666666666
78Z|010041586|0000001|ANT33|2160119|A|1835100|3333333333
78Z|012344052|0000001|ANT50|2160203|A|1219570|5555555555
    
por 23.02.2016 / 02:11
3

tente

awk 'BEGIN { FS="|"}
     FNR == NR { key[$2 $1]=NR }
     FNR > NR { k=$3 $8 ;if (k in key)  print ;} ' file2.txt file1.txt

onde

  • BEGIN { FS="|"} informa ao aw para usar | como separador (você pode usar -F\| na linha de comando)
  • FNR == NR { key[$2 $1]=NR } recorda a chave do arquivo (quando no arquivo2.txt)
  • FNR > NR { k=$4 $8 ;if (k in key) print ;} se a chave na lista de hash, imprimi-lo

Edit: você menciona o terceiro arquivado e entra no quarto.

    
por 22.02.2016 / 21:10
3

Simplificando, assumindo que no arquivo2 não é permitido dar o mesmo primeiro campo duas vezes:

awk -F'|' 'FNR == NR { key[$1] = $2; next } $8 in key && key[$8] == $4' file2.txt file1.txt
    
por 22.02.2016 / 21:42