Linux读取日志文件并进行筛选,以仅获取一次相同类型的日志消息
在我的日志文件中,我有三种类型的日志消息:信息、警告和错误。我只想抓取错误消息,但由于存在不同类型的错误消息,并且同一错误消息可能会在日志文件中出现多次,因此我只想抓取每种类型的错误消息 只有一次。我可以在Ubuntu终端中使用什么命令?我试过:Linux读取日志文件并进行筛选,以仅获取一次相同类型的日志消息,linux,shell,ubuntu,grep,uniq,Linux,Shell,Ubuntu,Grep,Uniq,在我的日志文件中,我有三种类型的日志消息:信息、警告和错误。我只想抓取错误消息,但由于存在不同类型的错误消息,并且同一错误消息可能会在日志文件中出现多次,因此我只想抓取每种类型的错误消息 只有一次。我可以在Ubuntu终端中使用什么命令?我试过: grep -E 'level=error' server.log | sort --unique 但这也给了我“信息”和“警告”信息 然后我使用了这个命令,但仍然得到了所有三种类型的消息,而不仅仅是错误消息 grep 'error' server.l
grep -E 'level=error' server.log | sort --unique
但这也给了我“信息”和“警告”信息
然后我使用了这个命令,但仍然得到了所有三种类型的消息,而不仅仅是错误消息
grep 'error' server.log | uniq -f 1
参数-f1用于跳过timestamp字段,因为它总是唯一的
例如,我的日志消息是:
.
.
.
11-03-2020 11:53:32" level=info msg="Starting up" file="etc/load/startwith.txt"
11-03-2020 11:53:33" level=info msg="Started" file="etc/load/startwith.txt"
11-03-2020 11:54:29" level=warning msg="Some fields missing" file="etc/load/startwith.php"
11-03-2020 11:54:47" level=info msg="Started the process" file="etc/load/startwith.php"
11-03-2020 11:54:51" level=info msg="Connecting to database" file="etc/db/dbinfo.php"
11-03-2020 11:54:53" level=error msg="Database connection failed" file="etc/db/dbinfo.php"
11-03-2020 13:26:22" level=info msg="Started back-up process" file="etc/load/startwith.php"
11-03-2020 13:26:23" level=info msg="Starting up" file="etc/load/startwith.txt"
11-03-2020 13:26:26" level=error msg="Start up failed" file="etc/db/startwith.php"
11-03-2020 13:26:27" level=info msg="Starting up" file="etc/load/startwith.txt"
11-03-2020 13:26:31" level=error msg="Start up failed" file="etc/db/startwith.php"
11-03-2020 13:26:32" level=info msg="Starting up" file="etc/load/startwith.txt"
11-03-2020 13:26:35" level=warning msg="Duplicate fields found" file="etc/load/startwith.php"
11-03-2020 13:26:36" level=info msg="Started the process" file="etc/load/startwith.php"
11-03-2020 13:26:37" level=info msg="Connecting to database" file="etc/db/dbinfo.php"
11-03-2020 13:26:38" level=info msg="Success. Connected to the database" file="etc/db/db-success.php"
11-03-2020 13:26:38" level=info msg="Inserting data to database" file="etc/db/dboperation.php"
11-03-2020 13:26:39" level=warning msg="Null fields found" file="etc/db/dboperation.php"
11-03-2020 13:26:39" level=info msg="Data inserted" file="etc/db/dboperation.php"
11-03-2020 13:26:39" level=info msg="Disconnected" file="etc/db/dboperation.php"
11-03-2020 13:26:43" level=info msg="Inserting data to database" file="etc/db/dboperation.php"
11-03-2020 13:26:43" level=error msg="Required data missing" file="etc/db/dboperation.php"
11-03-2020 13:26:44" level=info msg="Inserting data to database" file="etc/db/dboperation.php"
11-03-2020 13:26:44" level=error msg="Required data missing" file="etc/db/dboperation.php"
.
.
.
上述日志中错误的预期输出(3种不同类型的错误,而不是总的错误发生次数)为:
11-03-2020 11:54:53" level=error msg="Database connection failed" file="etc/db/dbinfo.php"
11-03-2020 13:26:31" level=error msg="Start up failed" file="etc/db/startwith.php"
11-03-2020 13:26:44" level=error msg="Required data missing" file="etc/db/dboperation.php"
因此,本质上我需要过滤日志文件以获取错误消息,并且每种类型只有一个错误。命令
uniq-f1
按空格分割。它没有效果,因为第一个空格(时间)后面的字符串是唯一的
改用uniq-s 20。这将忽略前20个字符
它适用于时间戳,因为在大多数情况下时间戳的长度是固定的。命令
uniq-f 1
按空格分割。它没有效果,因为第一个空格(时间)后面的字符串是唯一的
改用uniq-s 20。这将忽略前20个字符
它适用于时间戳,因为在大多数情况下时间戳的长度是固定的。只是:
awk '/error/ && !seen[$4]++'
或者使用引号作为分隔符来包含完整的msg=“this text”
消息,如:
awk -F'"' '/error/ && !seen[$3]++'
您可以在没有awk-grep错误的情况下进行排序,然后nl
对行进行编号,然后sort-u
使用msg=
对字段进行唯一排序,然后对行号重新排序,并使用cut
删除行号。或者,可以使用sed
提取msg=“part”
,以简化sort
标记化。像这样:
grep error | sed 's/.* msg="\([^"]*\)"/\1\t&/' | nl -w1 |
sort -t $'\t' -u -k2,2 | sort -n -k1 | cut -f3-
只是:
或者使用引号作为分隔符来包含完整的msg=“this text”
消息,如:
awk -F'"' '/error/ && !seen[$3]++'
您可以在没有awk-grep错误的情况下进行排序,然后nl
对行进行编号,然后sort-u
使用msg=
对字段进行唯一排序,然后对行号重新排序,并使用cut
删除行号。或者,可以使用sed
提取msg=“part”
,以简化sort
标记化。像这样:
grep error | sed 's/.* msg="\([^"]*\)"/\1\t&/' | nl -w1 |
sort -t $'\t' -u -k2,2 | sort -n -k1 | cut -f3-
这回答了你的问题吗?抱歉,它没有回答我的问题,因为他正在比较(因此排除)包含时间戳的行的精确副本,而我只想在时间戳之后进行比较。所以<代码>awk'!看到[$4]+'
。。。他使用,
作为字段分隔符,并使用第一个字段。因此,使用另一个字段分隔符和另一个字段……这是否回答了您的问题?抱歉,它没有回答我的问题,因为他正在比较(因此排除)包含时间戳的行的精确副本,而我只想在时间戳之后进行比较。所以<代码>awk'!看到[$4]+'
。。。他使用,
作为字段分隔符,并使用第一个字段。因此,请使用另一个字段分隔符和另一个字段……您能描述一下!看到[$4]+
了吗?谢谢Kamil,如果我想在一个大日志文件中过滤所有三种类型的消息(信息、警告、错误),我该如何修改这个'/error/&&!看到[$4]+'
命令吗?awk'/error/'
类似于grep error
。只需删除”/error/&&
部分。您能描述一下是什么吗!看到[$4]+
了吗?谢谢Kamil,如果我想在一个大日志文件中过滤所有三种类型的消息(信息、警告、错误),我该如何修改这个'/error/&&!看到[$4]+'
命令吗?awk'/error/'
类似于grep error
。只需删除'/error/&&
部分