我正在尝试编写一个小的bash脚本,您可以在其中指定分钟数,它将显示最近X分钟的日志文件行。 要获得这些行,我使用的是sed
sed -n '/time/,/time/p' LOGFILE
在CLI上,这完全有效,但在我的脚本中却没有。
# Get date
now=$(date "+%Y-%m-%d %T")
# Get date minus X number of minutes -- $1 first argument, minutes
then=$(date -d "-$1 minutes" +"%Y-%m-%d %T")
# Filter logs -- $2 second argument, filename
sed -n '/'$then'/,/'$now'/p' $2
我尝试了不同的方法,似乎没有一种方法可以工作:
result=$(sed -n '/"$then"/,/"$now"/p' $2)
sed -n "/'$then'/,/'$now'/p" "$2"
sed -n "/$then/,/$now/p" $2
sed -n "/$then/,/$now/p" "$2
任何sugesstions?
我在Debian 5上,echo $SHELL
说/bin/sh
编辑:脚本不产生输出,因此不会显示错误。
在日志文件中,每个条目都以此2013-05-15 14:21:42,794
答案 0 :(得分:1)
不要用嵌套引号让自己头疼。使用-v
选项和awk
将shell变量的值传递给脚本:
#!/bin/bash
# Get date
now=$(date "+%Y-%m-%d %T")
# Get date minus X number of minutes -- $1 first argument, minutes
delta=$(date -d "-$1 minutes" +"%Y-%m-%d %T")
# Filter logs -- $2 second argument, filename
awk -v n="$now" -v d="$delta" '$0~n,$0~d' $2
也不要使用shell内置函数的变量名,即then
。
答案 1 :(得分:1)
我认为主要问题是您尝试通过字符串匹配执行算术比较。 sed -n '/23/,/27/p'
为您提供包含23
的第一行与包含27
的下一行(然后再从包含23
的下一行到下一行)之间的行包含27
,等等。它不为你提供包含23到27之间数字的所有行。如果输入看起来像
19
22
24
26
27
30
它不输出任何内容(因为没有23
)。使用字符串匹配的awk解决方案具有相同的问题。因此,除非您的then
日期字符串逐字地出现在日志文件中,否则您的方法将失败。您必须将日期字符串转换为数字(删除-
,<space>
和:
),然后使用算术比较检查结果数字是否在正确的范围内,而不是字符串匹配。这超出了sed的能力; awk和perl可以很容易地完成它。这是一个perl解决方案:
#!/bin/bash
NOW=$(date "+%Y%m%d%H%M%S")
THEN=$(date -d "-$1 minutes" "+%Y%m%d%H%M%S")
perl -wne '
if (m/^(....)-(..)-(..) (..):(..):(..)/) {
$date = "$1$2$3$4$5$6";
if ($date >= '"$THEN"' && $date <= '"$NOW"') {
print;
}
}' "$2"