![grep 从特定时间开始到文件末尾的日志文件](https://linux22.com/image/138606/grep%20%E4%BB%8E%E7%89%B9%E5%AE%9A%E6%97%B6%E9%97%B4%E5%BC%80%E5%A7%8B%E5%88%B0%E6%96%87%E4%BB%B6%E6%9C%AB%E5%B0%BE%E7%9A%84%E6%97%A5%E5%BF%97%E6%96%87%E4%BB%B6.png)
我有一个日志文件,每一行的开头都有日期和时间。
我需要从特定时间开始搜索日志文件到文件末尾。
例如:
Starting point: July 29 2018 21:00:00
End point : end of file
我担心的是,即使 的模式July 29 2018 21:00:00
不存在,我仍然可以得到例如之间的界限,July 29 2018 21:05:11
因为这仍然超出了July 29 2018 21:00:00
。
是awk
或sed
为此工作吗?
答案1
我将使用 perl 来实现这一点,以解析每一行的时间戳:
$ cat file
June 5 2018 00:00:00 do not print
July 29 2018 20:59:59 do not print
July 29 2018 21:00:00 print me
July 29 2018 21:00:01 print me
$ perl -MTime::Piece -sane '
BEGIN {
$start = Time::Piece->strptime($startdate, "%B %e %Y %T");
}
# the string "@F[0..3]" is the first 4 words on the line
$time = Time::Piece->strptime("@F[0..3]", "%B %e %Y %T");
print if $time >= $start;
' -- -startdate="July 29 2018 21:00:00" file
July 29 2018 21:00:00 print me
July 29 2018 21:00:01 print me
此版本的效率更高,因为一旦看到开始日期,它就会停止解析时间戳(假设文件按时间顺序递增):
perl -MTime::Piece -sane '
BEGIN {
$start = Time::Piece->strptime($startdate, "%B %e %Y %T");
}
unless ($go) {
$time = Time::Piece->strptime("@F[0..3]", "%B %e %Y %T");
$go = $time >= $start;
}
print if $go;
' -- -startdate="July 29 2018 21:00:00" file
答案2
尝试这个:
grepfromdate() {
readarray f < $1
fromdate=$(date +%s -d "$2")
for (( lineno=${#f[@]}-1 ; lineno>=0; lineno-- )) ; do
line=${f[$lineno]}
time_from_line=$(echo "$line" | grep -o "^[A-Z][a-z]* [0-9][0-9] [0-9][0-9][0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9]")
[[ $(date +%s -d "$time_from_line") -gt $fromdate ]] && echo "$line" || break
done | tac
}
用法:
grepfromdate "filename" "July 29 2018 21:00:00"
date
您可以传递任何可以读取的日期格式,例如2018-07-01
.如果日期的格式发生变化,您可以grep
据此更改模式。
答案3
您可以搜索与定义的字符串匹配的第一行(即July 29 2018 21:
晚上 9 点之后的所有内容)。如果您有此行号,则可以tail
以找到的行号开头的文件。
$ man tail
-n, --lines=[+]NUM
output the last NUM lines, instead of the last 10; or use -n +NUM to output starting with line NUM
我的例子:
$ log=/var/log/syslog
# get line number
$ first_line=$(grep -no "Aug 14 08:" $log | tail -n1 | cut -d: -f1)
# count the lines from $first_line to EOF
$ tail -n +$first_line $log | wc -l
24071
# output the content starting with $first_line
$ tail -n +$first_line $log
# line count of the whole file:
$ wc -l $log
70896 /var/log/syslog
答案4
和sed
你一起可以做到
sed -n '/July 29 2018 21:/,/$!d/p' file
这将为您提供 2018 年 7 月 29 日 21:** 和文件最后一行之间的所有行