Transposição de arquivo texto com o AWK [RESOLVIDO]

1. Transposição de arquivo texto com o AWK [RESOLVIDO]

Marcus Aurelio do Bomfim Visgueira
visgueira

(usa Slackware)

Enviado em 31/08/2018 - 15:51h

Olá Galera,

Estou com um arquivo txt com o seguinte formato:

WC.547 - SESSAO 1
02/02/2015 13.21.18 0527 10738 7295610 7495
NAO CADASTRADO PROTOCOLO: 47289
WC.601 - ACESSO AO ARQUIVO
02/02/2015 13.22.56 0527 10738 7295610 AUT 0174
TERMINAL: 0527-2 PROTOCOLO: 000057420-0
USUÁRIO.................:KASSIA ZAMPRONHA MULLER
AUT: 145764
AUT. SAIDA.: 542147
AUT. FINAL: 543412
WC.601 - ACESSO AO ARQUIVO
02/02/2015 13.23.15 0527 10838 8385610 AUT 0175
TERMINAL: 2808-2 PROTOCOLO: 02123083-7
USUARIO: DANILO CASSEMIRO E SILVA
AUT.: 4571436
AUT. SAIDA: 563335
AUT. FINAL: 531976

Pretendo tabular, com o uso do AWK ou SED, esses registros de tamanhos diferentes e que se iniciam pela string "WC.", onde cada linha, ao final corresponderá a um registro, da seguinte forma:

WC.547 - SESSAO 1; 02/02/2015 13.21.18 0527 10738 7295610 7495; NAO CADASTRADO PROTOCOLO: 47289
WC.601 - ACESSO AO ARQUIVO; 02/02/2015 13.22.56 0527 10738 7295610; AUT 0174 TERMINAL: 0527-2 PROTOCOLO: 00057420-0; USUÁRIO.................:KASSIA ZAMPRONHA MULLER; AUT: 145764; AUT. SAIDA.: 542147; AUT. FINAL: 543412;
WC.601 - ACESSO AO ARQUIVO; 02/02/2015 13.23.15 0527 10838 8385610 AUT 0175; TERMINAL: 2808-2 PROTOCOLO: 02123083-7; USUARIO: DANILO CASSEMIRO E SILVA; AUT.: 4571436; AUT. SAIDA: 563335; AUT. FINAL: 531976

Alguém tem alguma ideia de como fazer?


  


2. Re: Transposição de arquivo texto com o AWK

Marcelo Oliver
msoliver

(usa Debian)

Enviado em 31/08/2018 - 20:55h

Boa noite Visgueira, segue sugestão...
sed '/ACESSO AO ARQUIVO/s/^/\n/' texto.txt|awk 'BEGIN{FS="\n";RS="\n\n"}{for(n=1;n<=NF;n++) printf "%s; " ,$n;printf "\n"}' 

Obs.: E não esqueça . . . Se te ajudei, me ajude, é simples.... Só marcar como a MELHOR RESPOSTA . . . Rsrsrsr

EDITADO em 01/09/2018 22:44h
Segue uma opção com bash.

while read -r line;do
[[ ${line} =~ ^$ ]] && echo "" || echo -n "${line};"
done <<< $(sed '/ACESSO AO ARQUIVO/s/^/\n/' arquivo.txt)
echo

Att.: marcelo oliver


3. Re: Transposição de arquivo texto com o AWK

Paulo
paulo1205

(usa Ubuntu)

Enviado em 01/09/2018 - 15:20h

O algoritmo é o seguinte:

1. Inicialize seus dados:
  1.1. crie um buffer de texto com conteúdo vazio;
  1.2. posicione a posição de leitura no início do arquivo.
2. Se o fim do arquivo tiver sido alcançado,
  2.1. se o buffer não estiver vazio,
    2.1.1. imprima o conteúdo do buffer;
  2.2. encerre o programa.
3. Leia o conteúdo da próxima linha do arquivo (extirpando a quebra de linha ao final, se isso for relevante na ferramenta que você estiver usando para implementação).
4. Se a linha contiver o padrão de início de uma linha nova,
  4.1. se o buffer não estiver vazio,
    4.1.1. imprima o conteúdo do buffer, e
  4.2. atribua a linha linha lida ao buffer.
5. Caso contrário (em 4),
  5.1. acrescente o conteúdo da linha lida ao final do buffer (usando o separador que você achar conveniente).
6. Volte ao passo 2.


Você pode fazer isso usando apenas o Bash.
buffer=""  # 1.1
exec 3</caminho/do/arquivo.txt # 1.2
while read -u 3 linha; do # 2 e 3 (se chegou ao fim, a leitura interrompe o while)
if [[ "$linha" ~= '^WC\.' ]]; then # 4
[[ -n "$buffer" ]] && echo "$buffer" # 4.1 e 4.1.1
buffer="$linha" # 4.2
else # 5
buffer="$buffer; $linha" # 5.1.
done # 6
[[ -n "$buffer" ]] && echo "$buffer" # 2.1 e 2.1.1
exec 3<&- # Desfaz associação de arquivo (1.2, acima)


Com o awk, isso poderia ser feito mais ou menos do seguinte modo.
BEGIN { buffer="" }  # 1
{ # 2 e 3 (modo normal de execução do awk, de ler processar linhas enquanto elas existirem)
if(match($0, "^WC\\.")){ # 4
if(length(buffer)){ print buffer } # 4.1 e 4.1.1
buffer=$0 # 4.2
}
else { buffer=buffer "; " $0 } # 5 e 5.1
} # 6
END { if(length(buffer)){ print buffer; } } # 2.1 e 2.1.1


Pode ser que existam formas “criativas” usando pipelines com awk, sed ou tr, mas eu não creio que sejam muito melhores, tanto em clareza quanto em eficiência, do que o algoritmo acima.


4. Re: Transposição de arquivo texto com o AWK

Paulo
paulo1205

(usa Ubuntu)

Enviado em 01/09/2018 - 15:43h

paulo1205 escreveu:

Pode ser que existam formas “criativas” usando pipelines com awk, sed ou tr, mas eu não creio que sejam muito melhores, tanto em clareza quanto em eficiência, do que o algoritmo acima.


Auto-contradizendo-me, eis uma pérola.
awk '/^WC\./ { if(length(buf)){ print buf } buf=$0; next } {buf=buf "; " $0} END { if(length(buf)){ print buf } }' /caminho/do/arquivo 



5. Re: Transposição de arquivo texto com o AWK [RESOLVIDO]

Marcelo Oliver
msoliver

(usa Debian)

Enviado em 01/09/2018 - 22:42h

paulo1205 escreveu:

paulo1205 escreveu:

Pode ser que existam formas “criativas” usando pipelines com awk, sed ou tr, mas eu não creio que sejam muito melhores, tanto em clareza quanto em eficiência, do que o algoritmo acima.


Auto-contradizendo-me, eis uma pérola.
awk '/^WC\./ { if(length(buf)){ print buf } buf=$0; next } {buf=buf "; " $0} END { if(length(buf)){ print buf } }' /caminho/do/arquivo 


Boa noite Paulo.
Bastante interessante esse comando "awk"...
awk '/^WC\./ { if(length(buf)){ print buf } buf=$0; next } {buf=buf "; " $0} END { if(length(buf)){ print buf } }' /caminho/do/arquivo 

A var "buf" é a linha?
Daria para explicar, por favor.
Abç.:
Marcelo Oliver



6. Re: Transposição de arquivo texto com o AWK

Paulo
paulo1205

(usa Ubuntu)

Enviado em 02/09/2018 - 15:35h

É o mesmo algoritmo que eu descrevi em minha primeira mensagem, mas usando a facilidade natural de executar blocos condicionalmente, em função da presença de uma expressão regular, se tal expressão for especificada antes do bloco de código (semelhante ao uso de expressão regular antes de um comando do ed ou sed).

As maiores diferenças dessa versão são a presença do comando next, que faz com que o awk passe diretamente para a próxima linha do texto de entrada, sem que os demais blocos sejam executados, e o bloco que executa somente após o fim do arquivo, por causa do padrão de execução condicional “END”.

awk '  # 2 e 3
/^WC\./ { # 4
if(length(buf)){ print buf } # 4.1 e 4.1.1
buf=$0; # 4.2
next # 6 (faz pular os demais blocos de código, no caso, apenas um)
}
{ buf=buf "; " $0 } # 5 e 5.1
# 6
END { # 2
if(length(buf)){ print buf } # 2.1 e 2.1.1
} # 2.2
' /caminho/do/arquivo # 1, 1.2 (1.1 é implícito: variáveis a que não se atribui valor têm valor vazio quando usadas).



7. Re: Transposição de arquivo texto com o AWK [RESOLVIDO]

Marcus Aurelio do Bomfim Visgueira
visgueira

(usa Slackware)

Enviado em 04/09/2018 - 05:05h

paulo1205 escreveu:

É o mesmo algoritmo que eu descrevi em minha primeira mensagem, mas usando a facilidade natural de executar blocos condicionalmente, em função da presença de uma expressão regular, se tal expressão for especificada antes do bloco de código (semelhante ao uso de expressão regular antes de um comando do ed ou sed).

As maiores diferenças dessa versão são a presença do comando next, que faz com que o awk passe diretamente para a próxima linha do texto de entrada, sem que os demais blocos sejam executados, e o bloco que executa somente após o fim do arquivo, por causa do padrão de execução condicional “END”.

awk '  # 2 e 3
/^WC\./ { # 4
if(length(buf)){ print buf } # 4.1 e 4.1.1
buf=$0; # 4.2
next # 6 (faz pular os demais blocos de código, no caso, apenas um)
}
{ buf=buf "; " $0 } # 5 e 5.1
# 6
END { # 2
if(length(buf)){ print buf } # 2.1 e 2.1.1
} # 2.2
' /caminho/do/arquivo # 1, 1.2 (1.1 é implícito: variáveis a que não se atribui valor têm valor vazio quando usadas).


Show!!!! Funcionou de primeira, conforme esperava. Muito obrigado!






Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts