Único registro de um arquivo sendo dividido em várias linhas

3

Estamos usando arquivos de texto simples para armazenar na tabela teradata após as transformações da Informatica. O arquivo contém 14 campos (separados por ~). Mas como os registros estão sendo espalhados em várias linhas, a informatica não é capaz de captá-lo.

Existe alguma maneira de juntarmos o registro contando o delimitador usando sed / awk ou qualquer outro comando?

Registro de amostra ---

48602040112~4100010080701242015~2010-01-21 10:23:44~Foods~7~Poultry ~Perdue Smart Chicken~Circular~06
-JAN-10~24-JAN-10~$5.99~24 oz., select varieties
up to 4 at this price, additional
Save up to $4.00 
load up on savings~~1598

Idealmente, deve ser como -

48602040112~4100010080701242015~2010-01-21 10:23:44~Foods~7~Poultry ~ Perdue Smart Chicken~Circular~06-JAN-10~24-JAN-10~$5.99~24 oz., select varieties up to 4 at this price, additional Save up to $4.00 load up on savings~~1598

Se não for óbvio, contém novos caracteres de linha.

    
por ckp 20.02.2015 / 16:04

3 respostas

1

tr -d \n <infile | tr \~ \n | paste -d~ - - - - - - - - - - - - - -

Isso vai funcionar.

    
por 25.06.2015 / 08:27
0

Você pode tentar usar sed :

sed -rn ':a;/^([^~]*~){13}[^~]*$/!{N;s/\n//;ba};p' yourfile.tsv

O que faz

O script tem três partes separadas por um ; :

  • :a define um rótulo que podemos ramificar para
  • /^([^~]*~){13}[^~]*$/!{N;s/\n//;ba} procura por uma coluna completa
    • /^([^~]*~){13}[^~]*$/ procura por uma linha com exatamente 14 campos (0 ou mais ocorrências de qualquer coisa que não seja ~ ), separadas por 13 ocorrências de ~ .
    • ! Inverte o resultado da pesquisa (se não for encontrado, então ...)
    • {N;s/\n//;ba} do bloco que é executado se a coluna não estiver completa
      • N lê em outra linha
      • s/\n// remove a nova linha entre as duas linhas
      • ba ramificações (b) para o nosso rótulo previamente definido (a)
  • p imprime a coluna completa
por 20.02.2015 / 17:23
0

Não está claro como decidir se deseja ingressar em um campo dividido com um espaço ou sem espaço. 06<NL>-JAN-10 precisa ter a nova linha removida, enquanto varieties<NL>up to precisa substituí-la por um espaço.

Ignorando a preocupação acima, podemos chegar a este protótipo do comando Awk:

$ awk 'BEGIN { RS = "~" }
       { gsub(/\n/,"",$0);
         printf("%s", $0);
         if (++i < 14) { printf("~"); }
         else { i = 0; printf("\n"); } }' < in.txt > out.txt

Recebemos o awk para dividir os registros em ~ para que cada campo seja realmente um registro. Em seguida, apenas apare os espaços em branco de cada registro com gsub e imprima-o seguido pelo separador, se for o campo 1 a 13, ou então seguido por uma nova linha, se for 14 (e redefina a contagem).

Se o número de campos não for divisível por 14, você receberá uma última linha incompleta na saída, terminada por ~ em vez de nova linha.

Uma maneira possível de lidar com o problema da junção é deixar as novas linhas no lugar ou, possivelmente, substituí-las por algum caracter que não ocorra nos dados. Faça a junção como uma etapa de pós-processamento. Suponha que @ não ocorra nos dados. Se substituirmos as novas linhas por @ , poderemos aplicar algumas substituições de padrão simples com as ferramentas usuais de processamento de texto. Por exemplo, a substituição ao longo das linhas de s/([0-9])@-/-/ manipula datas quebradas como 06@-JAN .

Pode ser necessário que essa lógica entenda o tipo de dados do campo específico que requer remoção de nova linha, para que ele possa, por exemplo, tratar datas especialmente.

    
por 25.06.2015 / 01:59