AWK: Processando mais de um tipo de separador de campo em arquivo único

2

O arquivo de origem contém campos delimitados por vírgulas e delimitados por tubos. Ele também contém registros de cabeçalho duplicados, separados por vírgulas e canais.

** Arquivo Souce **

FOOID|BIZNO|BARBIZ_CODE
00033567|0035952|A,KEEP
00034145|0036865|A,KEEP
FOOID|BIZNO|BARBIZ_CODE
00030527|0032479|Z4,KEEP
00034984|0037987|Z5,KEEP
FOOID|BIZNO|BARBIZ_CODE
00021826|0022008|Z5,KEEP
00026763|0029293|Z5,KEEP
FOOID,BIZNO,BARBIZ_CODE
A0021826,Q022008,Z5,TRASH
B0021826,R022009,Z5,TRASH
C0021826,S022018,Z5,TRASH
FOOID,BIZNO,BARBIZ_CODE

Eu quero manter apenas um cabeçalho delimitado por um pipe e todos os registros delimitados por canal.

Ignore o seguinte:

  1. Todos os registros e cabeçalhos de campos delimitados por vírgulas

  2. Cabeçalhos delimitados por pipe duplicado.

Suposições

  1. Primeiro campo no cabeçalho do delimitador de pipe = FOOID

  2. Campos delimitados por pipe podem conter vírgulas.

Este script awk remove duplicados cabeçalhos de pipe duplicados do meu arquivo. Como faço para ignorar todos os registros CSV?

#!/usr/bin/awk -f
BEGIN{ FS="|"
      header_f1 = "FOOID" }
{
if (NR==1) { print $0 }
if (NR>1 && $1 != header_f1 && length > 1) { print $0 }
}

Resultados desejados

FOOID|BIZNO|BARBIZ_CODE
00033567|0035952|A,KEEP
00034145|0036865|A,KEEP
00030527|0032479|Z4,KEEP
00034984|0037987|Z5,KEEP
00021826|0022008|Z5,KEEP
00026763|0029293|Z5,KEEP
    
por zundarz 17.11.2017 / 19:34

2 respostas

1

Abordagem curta awk :

awk -F'|' 'NR==1{ h=$1; print }NF>1 && NR>1 && $0!~"^"h' file
  • -F'|' - trata | como separador de campos
  • NR==1{ h=$1; print } - ao encontrar o primeiro registro, atribua o primeiro campo de cabeçalho $1 à variável h (como a indicação da linha de cabeçalho)
  • NF>1 - imprime registros com pelo menos 2 " | " - campos delimitados
  • $0!~"^"h - verificação adicional para garantir que o registro não se relaciona com a linha de cabeçalho

A saída:

FOOID|BIZNO|BARBIZ_CODE
00033567|0035952|A,KEEP
00034145|0036865|A,KEEP
00030527|0032479|Z4,KEEP
00034984|0037987|Z5,KEEP
00021826|0022008|Z5,KEEP
00026763|0029293|Z5,KEEP
    
por 17.11.2017 / 19:43
2

Considerando sua entrada de amostra, parece funcionar:

$ awk 'NR == 1 { print } /,/ && /\|/ { print }' input
FOOID|BIZNO|BARBIZ_CODE
00033567|0035952|A,KEEP
00034145|0036865|A,KEEP
00030527|0032479|Z4,KEEP
00034984|0037987|Z5,KEEP
00021826|0022008|Z5,KEEP
00026763|0029293|Z5,KEEP

Sempre imprima o primeiro registro (cabeçalho); Daí em diante imprimir apenas registros com uma vírgula e um pipe.

    
por 17.11.2017 / 19:39

Tags