我正在搜索日志文件,试图确定用户登录的总时间。我已经删除了与登录和注销无关的所有行。但是,出于某种原因,我们的登录行没有相应的注销行,所以我想删除它们。例如:
2013-04-07 08:44:01 [INFO] User logged in
2013-04-07 08:54:55 [INFO] User logged in
2013-04-07 08:57:12 [INFO] User logged in
2013-04-07 08:59:45 [INFO] User logged in
2013-04-07 09:01:28 [INFO] User logged in
2013-04-07 09:11:00 [INFO] User logged in
2013-04-07 09:12:56 [INFO] User logged in
2013-04-07 09:15:43 [INFO] User lost connection
我只想
2013-04-07 09:12:56 [INFO] User logged in
2013-04-07 09:15:43 [INFO] User lost connection
答案 0 :(得分:1)
这个awk单行可以解决问题:(至少对你的例子来说,我看不到的真实文件)
awk -F\[ '{a[$2]=$0;}END{for(x in a)print a[x]}' file
使用您的数据进行测试:
kent$ echo "2013-04-07 08:44:01 [INFO] User logged in
2013-04-07 08:54:55 [INFO] User logged in
2013-04-07 08:57:12 [INFO] User logged in
2013-04-07 08:59:45 [INFO] User logged in
2013-04-07 09:01:28 [INFO] User logged in
2013-04-07 09:11:00 [INFO] User logged in
2013-04-07 09:12:56 [INFO] User logged in
2013-04-07 09:15:43 [INFO] User lost connection"|awk -F\[ '{a[$2]=$0;}END{for(x in a)print a[x]}'
2013-04-07 09:12:56 [INFO] User logged in
2013-04-07 09:15:43 [INFO] User lost connection
对于相同的登录,只会打印出最后一个。
编辑
我认为您的真实文件可能就是这种情况:
您可能有多个登录丢失的连接块,例如:
kent$ cat file
2013-04-07 09:11:00 [INFO] User logged in
2013-04-07 09:12:56 [INFO] User logged in
2013-04-07 09:15:43 [INFO] User lost connection
2013-04-08 09:11:00 [INFO] User logged in
2013-04-08 09:12:56 [INFO] User logged in
2013-04-08 09:15:43 [INFO] User lost connection
然后这条线适合你:
awk '/lost/{print a;print;next;}{a=$0}' file
输出是:
2013-04-07 09:12:56 [INFO] User logged in
2013-04-07 09:15:43 [INFO] User lost connection
2013-04-08 09:12:56 [INFO] User logged in
2013-04-08 09:15:43 [INFO] User lost connection
答案 1 :(得分:1)
假设一行中永远不会有多个User lost connection
行,则以下内容应该有效:
sed '/User logged in/{h;d};H;x' file
或者如果您使用的系统不支持;
作为命令分隔符:
sed -e '/User logged in/{h
d
}' -e 'H' -e 'x' file
答案 2 :(得分:1)
我可以展示一个awk解决方案。如果一行包含“登录”字符串保存该行。如果该行不包含“登录”字符串,则打印最后存储的行并打印当前行。如果可能存在两个彼此跟随的“丢失连接”线,则可能会出现问题。 Awk也是过滤掉其他行的好选择。
#!/bin/bash
awk '!/logged in/ {print x"\n"$0} {x = $0}' <<EOT
2013-04-07 08:44:01 [INFO] User logged in
2013-04-07 08:54:55 [INFO] User logged in
2013-04-07 08:57:12 [INFO] User logged in
2013-04-07 08:59:45 [INFO] User logged in
2013-04-07 09:01:28 [INFO] User logged in
2013-04-07 09:11:00 [INFO] User logged in
2013-04-07 09:12:56 [INFO] User logged in
2013-04-07 09:15:43 [INFO] User lost connection
EOT
答案 3 :(得分:0)
这可能适合你(GNU sed):
sed -r '$!N;/(User logged in)\n.*\1/D' file