在 awk 中进行模式匹配后,如何匹配日期以确保匹配是最新的?

在 awk 中进行模式匹配后,如何匹配日期以确保匹配是最新的?

基本上我正在查看这样的日志条目:

*** Send Command has completed Successfully 
Transmitted 508200 bytes in 1 seconds
File Transfer Complete
RemoteTransactionNumber is ***********
************Server: Transfer Mode Set To Send
: *********************************************************50 al**********b:Y 
lf:"*********************************************************" rf:"*************
*(+1)" **************************************41
2017/04/18 13:05:32 About to execute the following Send command:

我定义了一个变量 $LOGGER 并将记录的数据存储在其中,因为它位于远程服务器上。我还创建了一个名为 $currentdate 的变量并存储:

currentdate=$(date +"%Y/%m/%d/ %I")

所以我提出这个问题的当前时间如下:2017/04/19/01

假设我想匹配“发送命令已成功完成”,我已经完成了以下操作:

ALERT=$(echo "$LOGGER" | awk "/Send Command has completed Successfully/" | grep -A 12 $currentdate)

然后,我尝试向前 12 行 grep 查找当前日期和时间(最多一个小时),以确保我匹配的发送是最新的,因为这就是此脚本运行时我所关心的。

但是最后一个 awk | grep -A 12 命令不起作用...有什么想法可以在命中 awk 匹配后查找日期并验证它与 $currentdate 匹配吗?这一切都是在从 SSH pass 命令检索日志抓取后在局部变量上完成的(仅供参考),因此此时没有实际的文件被操作。

编辑:因此,为了更清楚地了解我为什么在这里做我想做的事情,我需要报告当前时间的任何匹配。并且日期在“发送成功”条目的 12 行以内。我实际上正在使用 SSH 远程访问服务器,获取过去一小时写入的日志文件的数量。然后我将获取每行的最后 100 行并将其存储在 $Logger 变量中,如下所示:

COMMAND1="find /xxy -mmin -60 | wc -l"
FILENUM=`/xxy-1.05/sshpass  -p$PASS ssh -q -o StrictHostKeyChecking=no -o 
ConnectTimeout=310 $USER@$HOST "$COMMAND1"

COMMAND2="find /xxy -mmin -60 | tail -n $FILENUM | xargs tail -n100"
LOGGER=`/xxy-1.05/sshpass  -p$PASS ssh -q -o StrictHostKeyChecking=no -o 
ConnectTimeout=310 $USER@$HOST "$COMMAND2"

因此,考虑到我需要查看每场比赛的日期,我不确定最好的方法是将其干净地存储在变量中(awk 倾向于这样做以及为什么它是我的第一选择)

答案1

当某些东西不起作用时,您应该尝试将其拆开并查看各个部分的作用,以便找出故障所在。尝试一下这个命令:

echo "$LOGGER" | awk "/Send Command has completed Successfully/"

你得到了什么?只是*** Send Command has completed Successfully线。所以当然 grep 查找日期是行不通的;该行不包含日期。

如果你想要 awk 解决方案,请尝试类似的方法

echo "$LOGGER" | awk -vc="$currentdate" '
    /Send Command has completed Successfully/ { flag1=1 }
    $0 ~ c { flag2=1 }
END { if (flag1 && flag2) print "Yes"; else print "No" }'

它将 shell 变量currentdate作为 awk 变量传递到 awk 中c ,然后检查它和“Send Command …”字符串是否都存在于输入中。

顺便说一下,

  • 您应该始终引用您的 shell 变量引用(例如,"$currentdate"),除非您有充分的理由不这样做,并且您确定您知道自己在做什么。只要其中有空格,如果没有引号,您的grep … $currentdate命令就永远无法工作。"$currentdate"
  • 如果您想验证日志条目是否是最新的,则不应%Idate命令中使用 - 它返回 01..12 范围内的小时。所以,

    • 如果日志条目来自凌晨 1 点(因此显示“ 2017/04/18 01:##:## About to execute the following Send command:…”)并且当前时间为下午 1 点,则您的$currentdate变量将为2017/04/18 01 ,因此它会显示 12 小时前的消息是当前的,但是
    • 如果,如您的示例中所示,日志条目来自下午 1 点(因此显示“ 2017/04/18 13:05:32 About to execute the following Send command:…”)并且当前时间为下午 1 点,则您的$currentdate变量将(再次)为2017/04/18 01 ,因此它会表示当前消息不是当前消息。

    您应该使用%H,其范围为 (00..23)。

答案2

编辑:看来您不确定记录器中的日期顺序,所以我更改了我的条目以匹配“任何地方”的日期

您的示例没有显示多个条目,所以我假设它们是:

2017/04/....
(several lines)
*** Send Command has completed Successfully
2017/04/.... (another time, maybe before or after, no ordering )
(several lines)
2017/04/.... (another time, maybe before or after, no ordering )
(several lines)
2017/04/.... (another time, maybe before or after, no ordering )
(several lines)
2017/04/.... (another time, maybe before or after, no ordering )
(several lines)
*** Send Command has completed Successfully
2017/04/.... (another time, maybe before or after, no ordering )
(several lines)
2017/04/.... (another time, maybe before or after, no ordering )

我相信你只需要:

dateappearsas="^[0-9][0-9][0-9][0-9]/[0-9][0-9]/"
looking_for="Send Command has completed Successfully"

echo "$LOGGER" \
| egrep -i "${dateappearsas}|${looking_for}" \
|  grep -i -B 1 "${looking_for}" \
| grep -A 1 "$currentdate"
returncode="$?" # in bash, gets the latest command in the preceding pipe, ie the grep's exit code
# the egrep: outputs all dates, and interspered among those some "successfully"
# the 2nd grep: transform those into pairs of date & successfully
# the last grep find only the matching currentdate and the line after it  
if [ "$returncode" = "0" ]
then
   echo "There is a transfer that matches the current date, AND was successful"
else
   echo "There is either no date matching the current date, or it wasn't successfull"
fi

基本上:egrep 获取您正在寻找的内容和上下文(此处:日期)。它可能提供了几行上下文,其中一些也有您正在寻找的东西。然后grep -B 1 'what your are looking for'将重新组合这些: context/lookedfor 对在一起(将查找的行和之前的日期放在一起),最后一个 grep 查找当前日期是否在这些对中

相关内容