Quero converter meu arquivo txt para xls/csv.
A primeira linha deve imprimir data e hora e a segunda linha deve imprimir todos os dados restantes (de tid à tabela no exemplo abaixo)
Quando estou usando o comando abaixo
awk 'BEGIN{ OFS="\t"; print "DateTime,Error"}; NR > 1{print $1,$2;}' TMP.txt > Output.xls
Está imprimindo data e hora na primeira linha, mas apenas imprimindo tid na próxima coluna.
Alguém pode me ajudar a imprimir todo o texto restante na segunda coluna
Grave em arquivo de texto:
2019-11-26T11:51:32.087-08:00 tid: JCA-work-instance:AQ Adapter-8 userId: <anonymous> 0 , APP: Service Bus Logging FlowId: 0000MtDbHiu8pmk5Szd9ic1TlVox0015xl RouteNode2, null, null, REQUEST Queried data from header table
Os seguintes tipos de entradas de log também devem ser considerados:
Nov 28, 2019 8:19:03 AM PST HTTP BEA-101019 [ServletContext[text] Servlet failed with an IOException.
Nov 28, 2019 8:22:40 AM PST [null, null, null, ERROR] error in service-callouterror service to get information
Responder1
A razão para o comportamento que você vê é que, por padrão, awk
trata WHITESPACE
(ou seja, espaço, tabulação) como separador de campo de entrada. Por isso,todoO item em seu arquivo de entrada que está cercado por espaço é tratado como um único "campo" e recebe sua própria $<number>
variável interna. Seu awk
comando, no entanto, instrui awk
a imprimir apenas os dois primeiros campos ( $1
e $2
), que são, no seu caso, a string de data/hora e o literal tid:
.
No seu caso particular, a maneira mais fácil pode ser sed
substituir oprimeiroespaço em branco por um tabulador, que deve dar o resultado desejado.
Como você também deseja incluir uma linha de cabeçalho, o seguinte deve funcionar (assumindo que o GNU sed
esteja sendo usado):
sed -e '1 i\DateTime\tError' -e 's/ /\t/' TMP.txt > Output.txt
A primeira expressão insere uma linha de texto no início da linha, a segunda executa a "formatação real" pretendida.
Atualizar
Para o formato de string adicional que você forneceu, eu recorreria awk
em vez de sed
(observe que uso GNU awk):
awk 'BEGIN{printf("DateTime\tError\n")} {match($0,"^([[:alpha:]]{3}[[:space:]]+[0123]?[[:digit:]],[[:space:]]+20[[:digit:]]{2}[[:space:]]+[01]?[[:digit:]]:[012345][[:digit:]]:[012345][[:digit:]][[:space:]]+[AP]M[[:space:]]+[[:alpha:]]+)[[:space:]]+([[:print:]]*)$", fields); printf("%s\t%s\n", fields[1], fields[2])}' TMP.txt > Output.txt
Esta expressão regular corresponde a um formato de hora especificado por você, seguido por um ou mais espaços, seguido por caracteres imprimíveis arbitrários até o final da linha e imprime o primeiro (...)
subgrupo, o carimbo de data/hora, depois a e \t
, em seguida, o segundo (...)
subgrupo, que é "o resto da linha". Além disso, a BEGIN
âncora é usada para inserir a linha do cabeçalho no topo.
Como ambos os casos podem ocorrer no mesmo arquivo, temos que combiná-los em um único awk
programa:
BEGIN {
printf("DateTime\tError\n");
}
{
if (match($0,"^([[:alpha:]]{3}[[:space:]]+[0123]?[[:digit:]],[[:space:]]+20[[:digit:]]{2}[[:space:]]+[012]?[[:digit:]](:[012345][[:digit:]]){2}[[:space:]]+[AP]M[[:space:]]+[[:upper:]]+)[[:space:]]+([[:print:]]*)$", fields) == 0)
match($0,"^(20[[:digit:]]{2}-[01][[:digit:]]-[0123][[:digit:]][[:alpha:]][012][[:digit:]](:[012345][[:digit:]]){2}.[[:digit:]]{3}[+-][012][[:digit:]]:[012345][[:digit:]])[[:space:]]+([[:print:]]*)$", fields);
printf("%s\t%s\n", fields[1], fields[3]);
}
Você pode chamar o script acima xlsconvert.awk
e depois chamá-lo como
user@host$ awk -f xlsconvert.awk TMP.txt > Output.txt
Observe que isso, é claro, manterá os diferentes formatos de carimbo de data/hora na saída. Se você quiser convertê-lo para um formato unificado, talvez seja necessário recorrer a um script de shell.