如何在 Unix 中将 txt 编辑为 xls?

如何在 Unix 中将 txt 编辑为 xls?

我想将 txt 文件转换为 xls/csv。

第一行应打印日期时间,第二行应打印剩余的所有数据(从 tid 到下面示例中的表)

当 m 使用以下命令时

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

它在第一行打印日期时间,但仅在下一列打印 tid。

谁能帮我打印第二列中剩余的全部文本

记录在文本文件中:

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

还应考虑以下类型的日志条目:

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

答案1

您看到的行为的原因是,默认情况下,awkWHITESPACE(即空格、制表符)视为输入字段分隔符。因此,每一个输入文件中被空格包围的项目被视为单个“字段”,并分配有自己的$<number>内部变量。但是,您的awk命令指示 awk仅打印前两个此类字段($1$2),在您的情况下是日期/时间字符串和文字tid:

在您的特定情况下,最简单的方法可能是使用sed替换第一的制表符的空白,这应该给出所需的结果。

由于您还想包含标题行,因此以下内容应该有效(假设sed正在使用 GNU):

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

第一个表达式在行首插入一行文本,第二个表达式执行预期的“实际格式化”。

更新

对于您提供的附加字符串格式,我将采用以下awk方法sed(请注意,我使用 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

此正则表达式匹配您指定的时间格式,后跟一个或多个空格,后跟任意可打印字符,直到行尾,并打印第一(...)个子组、时间戳,然后是 a \t,然后是第二个子组(...)子组,即“该行的其余部分”。此外,BEGIN锚点用于在顶部插入标题行。

由于这两种情况都可能发生在同一个文件中,因此我们必须将它们组合成一个awk程序:

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

您可以调用上面的脚本xlsconvert.awk,然后将其调用为

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

请注意,这当然会在输出中保留不同的时间戳格式。如果您想将其转换为统一格式,您可能必须求助于 shell 脚本。

相关内容