我的任务是执行以下操作:
从未给出名称的标准输入(可能是一个文件,但我不确切知道它)中,对其进行处理以重现此内容:
2021-07-06 - 12:45:12 - 218.251.25.78 - "Through bag smile international talk."
2021-07-06 - 12:45:12 - 213.255.42.89 - "Lay point red away member network."
^^^ ^^^ ^^^ ^^^
date hour(init) ip description
这将是标准输入给出的信息
Init: 2021-07-06 12:45:12
End: 2021-07-06 13:38:09
Logfile:
1625561998 218.251.25.78 CRITICAL "Through bag smile international talk."
1625573490 223.203.248.97 ERROR "Evening message suffer certainly pretty nothing she."
1625560753 36.254.92.124 DEBUG "Future suddenly guy issue Congress feeling."
1625563857 213.255.42.89 CRITICAL "Lay point red away member network."
1625560959 107.150.127.36 DEBUG "Center nothing approach."
1625579950 54.56.188.207 DEBUG "Then final simple door sell."
只应获取带有 CRITICAL 标志的日志。
因此,我假设一段时间读取行会起作用,但我不确定如何 grep 信息并获取部分信息,然后将其全部连接起来。也许在其他编程语言中会更容易,但在 Bash 中我不知道该怎么做。
** 编辑是因为我设法用 Bash 来完成它。问题是我正在搜索一个单词,所以如果这个单词在其他地方,而不仅仅是在 $3 字段中,它也会匹配,但这是不合适的。
#!/bin/bash
while read -r line
do
if echo $line | grep -q "CRITICAL"; then
epoch=$(echo $line | gawk '{$1 = strftime("%F %T", substr($1,1,10))} 1')
hDateIp=$(echo $epoch | sed 's/CRITICAL//g' | cut -d ' ' -f1-4 | sed 's/\ /\ \-\ /g')
msg=$(echo $epoch | cut -d '"' -f2)
echo $hDateIp \"$msg\"
fi
done < file-ingest
我还尝试将这一行包含在条件中,但没有成功,因为输出很奇怪:
if echo $line | awk -F '[]' '$3 == "CRITICAL"'
答案1
假设您希望将1625561998
... Unix 纪元时间转换为本地时间戳,而不是打印Init
每行的时间,使用perl
:
perl -MPOSIX -lne '
print strftime("%F - %T - ", localtime$1), "$2 - $3"
if /^(\d+) (\S+) CRITICAL (.*)/' <your-file
2021-07-06 - 09:59:58 - 218.251.25.78 - "Through bag smile international talk."
2021-07-06 - 10:30:57 - 213.255.42.89 - "Lay point red away member network."
(更改localtime
为gmtime
获取 UTC 时间而不是本地时间)。
任何状况之下你不应该使用 shell 循环来处理文本。
答案2
#! /bin/bash
read -r dummy date time rest
read -r ignore
read -r ignore
while read -r timestamp ip category text; do
if [ "$category" = 'CRITICAL' ]; then
printf '%s - %s - %s - %s\n' "$date" "$time" "$ip" "$text"
fi
done
答案3
使用Perl
(仅内置,无需安装模块):
我转换Unix epoch time
根据我们对您问题的评论,您在问题中指定的人类可读格式:
<INPUT> |
perl -MPOSIX -ane '
CORE::say join " ", strftime("%F - %T -", localtime $F[0]), @F[1..$#F]
if $F[0] =~ /^\d+$/ and $F[2] eq "CRITICAL"
'
2021-07-06 - 10:59:58 - 218.251.25.78 CRITICAL "Through bag smile international talk."
2021-07-06 - 11:30:57 - 213.255.42.89 CRITICAL "Lay point red away member network."