Wie kann ich unter Unix TXT in XLS umwandeln?

Wie kann ich unter Unix TXT in XLS umwandeln?

Ich möchte meine TXT-Datei in XLS/CSV konvertieren.

Die erste Zeile sollte Datum und Uhrzeit drucken und die zweite Zeile alle restlichen Daten (von TID bis Tabelle im folgenden Beispiel).

Wenn ich den folgenden Befehl verwende

awk 'BEGIN{ OFS="\t"; print "DateTime,Error"}; NR > 1{print $1,$2;}' TMP.txt > Output.xls

In der ersten Zeile wird das Datum und die Uhrzeit gedruckt, in der nächsten Spalte jedoch nur die Zeitangabe.

Kann mir bitte jemand helfen, den gesamten verbleibenden Text in der zweiten Spalte auszudrucken

Eintrag in Textdatei:

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

Die folgenden Arten von Protokolleinträgen sollten ebenfalls berücksichtigt werden:

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

Antwort1

Der Grund für das Verhalten, das Sie sehen, ist, dass standardmäßig (also Leerzeichen, Tabulator) als Eingabefeldtrennzeichen awkbehandelt wird . DaherWHITESPACEjedenEin Element in Ihrer Eingabedatei, das von Leerzeichen umgeben ist, wird als einzelnes „Feld“ behandelt und erhält eine eigene $<number>interne Variable. Ihr awkBefehl weist jedoch an, nur die ersten beiden dieser Felder ( und ) awkauszudrucken , was in Ihrem Fall die Datums-/Uhrzeitzeichenfolge und das Literal sind .$1$2tid:

In Ihrem speziellen Fall könnte der einfachste Weg sein, zu verwenden, sedum dieErsteLeerzeichen durch einen Tabulator, was zum gewünschten Ergebnis führen sollte.

Da Sie auch eine Kopfzeile einfügen möchten, sollte Folgendes funktionieren (vorausgesetzt, sedes wird GNU verwendet):

sed -e '1 i\DateTime\tError' -e 's/ /\t/' TMP.txt > Output.txt

Der erste Ausdruck fügt den Text am Zeilenanfang ein, der zweite führt die „eigentliche Formatierung“ durch.

Aktualisieren

Für das zusätzliche Zeichenfolgenformat, das Sie bereitgestellt haben, würde ich awkstattdessen auf Folgendes zurückgreifen sed(beachten Sie, dass ich GNU awk verwende):

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

Dieser reguläre Ausdruck sucht nach einem von Ihnen angegebenen Zeitformat, gefolgt von einem oder mehreren Leerzeichen, gefolgt von beliebigen druckbaren Zeichen bis zum Ende der Zeile, und druckt die erste (...)Untergruppe, den Zeitstempel, dann ein \tund dann die zweite (...)Untergruppe, die „der Rest der Zeile“ ist. Zusätzlich BEGINwird der Anker verwendet, um die Kopfzeile oben einzufügen.

Da beide Fälle in derselben Datei auftreten können, müssen wir sie in einem einzigen awkProgramm kombinieren:

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]);
}

Sie können das obige Skript aufrufen xlsconvert.awkund es dann als

user@host$ awk -f xlsconvert.awk TMP.txt > Output.txt

Beachten Sie, dass dadurch natürlich die unterschiedlichen Zeitstempelformate in der Ausgabe erhalten bleiben. Wenn Sie diese in ein einheitliches Format konvertieren möchten, müssen Sie möglicherweise auf ein Shell-Skript zurückgreifen.

verwandte Informationen