我想将 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
您看到的行为的原因是,默认情况下,awk
将WHITESPACE
(即空格、制表符)视为输入字段分隔符。因此,每一个输入文件中被空格包围的项目被视为单个“字段”,并分配有自己的$<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 脚本。