我有几个日志包含所有以时间戳开头的行,以便以下工作按预期合并它们:
cat myLog1.txt myLog2.txt | sort -n > combined.txt
问题是,myLog2.txt还可以包含没有时间戳的行(例如java堆栈跟踪)。是否有一种简单的方法,没有任何自定义脚本仍然合并它们并保留多行内容?
示例 myLog1.txt
11:48:18.825 [main] INFO org.hibernate.cfg.Environment - HHH000206: hibernate.properties not found
11:48:55.784 [main] INFO o.h.tool.hbm2ddl.SchemaUpdate - HHH000396: Updating schema
示例 myLog2.txt
11:48:35.377 [qtp1484319352-19] ERROR c.w.b.c.ControllerErrorHandler -
org.springframework.beans.TypeMismatchException: Failed to convert value of type 'java.lang.String' to required type 'org.joda.time.LocalDate'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type java.lang.String to type @org.springframework.web.bind.annotation.RequestParam @org.springframework.format.annotation.DateTimeFormat org.joda.time.LocalDate for value '[2013-03-26]'; nested exception is java.lang.IllegalArgumentException: Invalid format: " [2013-03-26]"
at org.springframework.beans.TypeConverterSupport.doConvert(TypeConverterSupport.java:68) ~[spring-beans-3.2.1.RELEASE.jar:3.2.1.RELEASE]
at org.springframework.beans.TypeConverterSupport.convertIfNecessary(TypeConverterSupport.java:45) ~[spring-beans-3.2.1.RELEASE.jar:3.2.1.RELEASE]
at org.springframework.validation.DataBinder.convertIfNecessary(DataBinder.java:595) ~[spring-context-3.2.1.RELEASE.jar:3.2.1.RELEASE]
at org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver.resolveArgument(AbstractNamedValueMethodArgumentResolver.java:98) ~[spring-web-3.2.1.RELEASE.jar:3.2.1.RELEASE]
at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:77) ~[spring-web-3.2.1.RELEASE.jar:3.2.1.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:162) ~[spring-web-3.2.1.RELEAS
预期输出
11:48:18.825 [main] INFO org.hibernate.cfg.Environment - HHH000206: hibernate.properties not found
11:48:35.377 [qtp1484319352-19] ERROR c.w.b.c.ControllerErrorHandler -
org.springframework.beans.TypeMismatchException: Failed to convert value of type 'java.lang.String' to required type 'org.joda.time.LocalDate'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type java.lang.String to type @org.springframework.web.bind.annotation.RequestParam @org.springframework.format.annotation.DateTimeFormat org.joda.time.LocalDate for value '[2013-03-26]'; nested exception is java.lang.IllegalArgumentException: Invalid format: " [2013-03-26]"
at org.springframework.beans.TypeConverterSupport.doConvert(TypeConverterSupport.java:68) ~[spring-beans-3.2.1.RELEASE.jar:3.2.1.RELEASE]
at org.springframework.beans.TypeConverterSupport.convertIfNecessary(TypeConverterSupport.java:45) ~[spring-beans-3.2.1.RELEASE.jar:3.2.1.RELEASE]
at org.springframework.validation.DataBinder.convertIfNecessary(DataBinder.java:595) ~[spring-context-3.2.1.RELEASE.jar:3.2.1.RELEASE]
at org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver.resolveArgument(AbstractNamedValueMethodArgumentResolver.java:98) ~[spring-web-3.2.1.RELEASE.jar:3.2.1.RELEASE]
at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:77) ~[spring-web-3.2.1.RELEASE.jar:3.2.1.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:162) ~[spring-web-3.2.1.RELEAS
11:48:55.784 [main] INFO o.h.tool.hbm2ddl.SchemaUpdate - HHH000396: Updating schema
由于 马可
答案 0 :(得分:17)
我正在努力解决同样的问题,最后我想我已经得到了它。尝试这样做:
sort -nbms -k1.1,1.2 -k1.4,1.5 -k1.7,1.8 -k1.10,1.12 myLog1.txt myLog2.txt > combined.txt
我自己还不完全清楚,但我会尝试给出一些解释。根据使用的手册页面意思是:
-n, - numeric-sort - 根据字符串数值进行比较。
-b, - ignore-leading-blanks - 忽略前导空白。
-s, - stable - 通过禁用最后的比较来稳定排序
-m,--merge - 合并已排序的文件;不要排序
-k, - key = POS1 [,POS2] - 在POS1(原点1)开始一个键,在POS2(默认行尾)结束
-m
的原因。保持堆栈跟踪不被破坏是至关重要的。-b
不是必需的,因为以某种方式-n
和-m
组合使得堆栈跟踪线不会聚集。我留下它以防万一,因为大多数堆栈跟踪线都以空白开头。-n
显然会停止比较密钥。这是保持堆栈跟踪到位的第二个关键点。重要的是,如果它是-n -k1,1
,它只会按小时对日志文件进行排序,因为冒号是非数字的。除了-n
加速数字比较,所以无论如何我们想要它。-k1.1,1.2
(小时的第一和第二位)-k1.4,1.5
(第一和第二)分钟数)等等。点之前的第一个数字始终是' 1'因为它指向文件行的第一列(在我们的例子中是时间)。简而言之,-kA,B
A
和B
是给定行中的列位置(默认情况下,行由空格分隔)。使用的A和B的格式是..请记住,只要A
和B
之间存在非数字字符,如果使用了-n
,则在比较之后将忽略它。< / LI>
-s
禁用默认行为,即:每当进行比较的键都完成相同的完整字符串比较。我们不希望保留原始日志条目顺序。不确定-m
是否有必要。答案 1 :(得分:1)
Nope - 无法使用简单的命令IMMHO完成。
但是 - 这是一个脚本(这是一个挑战......)
@ECHO OFF
SETLOCAL
:: First log to tempfile
COPY /y mylog.txt "%temp%\combinedlogs.tmp" >NUL
(
FOR /f "delims=" %%i IN (mylog2.txt) DO (
SET line=%%i
ECHO %%i|FINDSTR /b /r "[012][0-9]:[0-5][0-9]:[0-5][0-9]\.[0-9][0-9][0-9]" >NUL
IF ERRORLEVEL 1 (
SETLOCAL ENABLEDELAYEDEXPANSION
ECHO(!stamp:~0,12!!count!!line!
ENDLOCAL
SET /a count+=1
) ELSE (
SET /a count=100
ECHO %%i
SET stamp=%%i
)
)
)>>"%temp%\combinedlogs.tmp"
(
FOR /f "delims=" %%i IN ('SORT "%temp%\combinedlogs.tmp"') DO (
SET line=%%i
SETLOCAL enabledelayedexpansion
IF "!line:~12,1!"==" " (ECHO(%%i) ELSE (ECHO(!line:~15!)
ENDLOCAL
)
)>combinedlogs.txt
DEL "%temp%\combinedlogs.tmp" /F /Q
将带有所有带时间戳的条目的第一个日志复制到临时文件
通过
Tempfile因此是
Timestamp1 line1 from file1
..
Timestampn linen from file1
timestampA line1 from file2 with timestamp
timestampA100 UNtimestamped line2from file2
timestampA101 UNtimestamped line3from file2
timestampB line4 from file2 with timestamp
timestampB100 UNtimestamped line5from file2
timestampB101 UNtimestamped line6from file2
...
对结果进行排序并重新处理
第13个字符中包含非空格的行是来自第二个文件的未加时间戳的行,因此
完成!
答案 2 :(得分:0)
您应该在日志文件中使用merge
,stable
,ignore-leading-blanks
,numeric-sort
以及易于排序的日期时间格式(例如yyyyMMddHHmmssSSS
)
因此,我更改了您的日志格式,以便更容易排序,从而产生sort -bsnm log1 log2
:
$ cat -n log1 log2 && sort -m -b -n -s log1 log2
1 114818825 [main] INFO org.hibernate.cfg.Environment - HHH000206 hibernate.properties not found
2 114855784 [main] INFO o.h.tool.hbm2ddl.SchemaUpdate - HHH000396 Updating schema
1 114835377 [qtp1484319352-19] ERROR c.w.b.c.ControllerErrorHandler -
2 org.springframework.beans.TypeMismatchException Failed to convert value of type 'java.lang.String' to required type 'org.joda.time.LocalDate'; nested exception is org.springframework.core.convert.ConversionFailedException Failed to convert from type java.lang.String to type @org.springframework.web.bind.annotation.RequestParam @org.springframework.format.annotation.DateTimeFormat org.joda.time.LocalDate for value '[2013-03-26]'; nested exception is java.lang.IllegalArgumentException Invalid format " [2013-03-26]"
3 at org.springframework.beans.TypeConverterSupport.doConvert(TypeConverterSupport.java68) ~[spring-beans-3.2.1.RELEASE.jar3.2.1.RELEASE]
4 at org.springframework.beans.TypeConverterSupport.convertIfNecessary(TypeConverterSupport.java45) ~[spring-beans-3.2.1.RELEASE.jar3.2.1.RELEASE]
5 at org.springframework.validation.DataBinder.convertIfNecessary(DataBinder.java595) ~[spring-context-3.2.1.RELEASE.jar3.2.1.RELEASE]
6 at org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver.resolveArgument(AbstractNamedValueMethodArgumentResolver.java98) ~[spring-web-3.2.1.RELEASE.jar3.2.1.RELEASE]
7 at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java77) ~[spring-web-3.2.1.RELEASE.jar3.2.1.RELEASE]
8 at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java162) ~[spring-web-3.2.1.RELEAS
9
114818825 [main] INFO org.hibernate.cfg.Environment - HHH000206 hibernate.properties not found
114835377 [qtp1484319352-19] ERROR c.w.b.c.ControllerErrorHandler -
org.springframework.beans.TypeMismatchException Failed to convert value of type 'java.lang.String' to required type 'org.joda.time.LocalDate'; nested exception is org.springframework.core.convert.ConversionFailedException Failed to convert from type java.lang.String to type @org.springframework.web.bind.annotation.RequestParam @org.springframework.format.annotation.DateTimeFormat org.joda.time.LocalDate for value '[2013-03-26]'; nested exception is java.lang.IllegalArgumentException Invalid format " [2013-03-26]"
at org.springframework.beans.TypeConverterSupport.doConvert(TypeConverterSupport.java68) ~[spring-beans-3.2.1.RELEASE.jar3.2.1.RELEASE]
at org.springframework.beans.TypeConverterSupport.convertIfNecessary(TypeConverterSupport.java45) ~[spring-beans-3.2.1.RELEASE.jar3.2.1.RELEASE]
at org.springframework.validation.DataBinder.convertIfNecessary(DataBinder.java595) ~[spring-context-3.2.1.RELEASE.jar3.2.1.RELEASE]
at org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver.resolveArgument(AbstractNamedValueMethodArgumentResolver.java98) ~[spring-web-3.2.1.RELEASE.jar3.2.1.RELEASE]
at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java77) ~[spring-web-3.2.1.RELEASE.jar3.2.1.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java162) ~[spring-web-3.2.1.RELEAS
114855784 [main] INFO o.h.tool.hbm2ddl.SchemaUpdate - HHH000396 Updating schema
如@Magoo's answer所述,您的日志日期时间目前格式化的方式很难排序。
答案 3 :(得分:0)
这是在bash shell中使用简单合并文件(而不是昂贵的求助 - 在日志文件已经排序的情况下)的一种方法。这对于数百兆字节或更多的大型文件非常重要,实际日志文件就是如此。
此解决方案假设您的日志中没有NUL字节,对于我遇到的每个日志文件都是如此,具有各种字符集。
基本理念:
sorn -m
以合并它们第一步是多次完成,我给它起了一个别名:
alias a="awk '{ if (match(\$0, /^[0-9]{2}:[0-9]{2}:[0-9]{2}\\./, _))\
{ if (NR == 1) printf \"%s\", \$0; else printf \"\\n%s\", \$0 }\
else printf \"\\0%s\", \$0 } END { print \"\" }'"
这是执行所有3个步骤的命令:
sort -m <(a myLog1.txt) <(a myLog2.txt) | tr '\0' '\n'
答案 4 :(得分:0)
开放源代码工具(Java GitHub)使您可以将包括多行在内的不同格式的日志文件合并到合并文件中。
该工具允许更改日志文件中记录的时间。当文件来自不同时区时很有用。
它还允许为合并的文件生成其他信息,例如统一格式的应用程序名称或时间戳,请参见the example。
该工具可用作command line tool或Java library。 注意:我是作者。