我想知道我该如何去做这件事。
这是我的输出的一个例子
Sun Aug 21 2016 03:00:00, BLAH
Mon Aug 22 2016 03:54:00, BLAH
Tue Aug 23 2016 04:22:11, BLAH
Thu Aug 25 2016 05:00:00, BLAH
现在我想做的只是数数连续的天,所以在上面的例子中应该说BLAH
出现了 3 次,因为它们是相继出现的。
我有 bash、awk 和 sed 可用。
答案1
在 AWK 中:
{
sub(",", "", $0); # kill first comma, thanks Thomas
cmd="date -d \""$1" "$2" "$3" "$4" "$5" 1 day ago\" \"+%b %e\"";
cmd|getline dt;
close(cmd);
if (dt==prev && blah==substr($0, index($0, $6))) { times = times + 1 }
else { print times" "line; times = 1 };
prev=$2" "$3;
blah=substr($0, index($0,$6));
line=$0;
}
END { print times" "line }
假设我们在名为的文件中有此输入blah.log
:
Sun Aug 21 2016 03:00:00, BLAH
Mon Aug 22 2016 03:54:00, BLAH
Tue Aug 23 2016 04:22:11, BLAH
Thu Aug 25 2016 05:00:00, BLAH
而 awk 脚本中consecutive.awk
,我们可以这样做:
$ awk -f consecutive.awk blah.log
3 Tue Aug 23 2016 04:22:11 BLAH
1 Thu Aug 25 2016 05:00:00 BLAH
它给出了连续天数作为额外的列并打印最后的日期。要删除输出中的日期,您只需更改print times" "line
为print times" "blah
(在出现的两个位置中)。
它是如何工作的:
- 执行日期命令以获取当前行的昨天,感谢 Glenn jackman
- 与上一行保存的日期进行比较
- 增加计数器或打印
- 保存当前行的数据以供下次运行
笔记:
- 它很丑陋(所有 AWK 代码都是如此,克服它)
- 可以在任何间隙(长达一整年)内正常工作,因为它使用
date
,但忽略时区 - 它认为 BLAH 在不同的行上可能不同,并且仅将 BLAH 出现与其他 BLAH 出现进行匹配。如果文件排序不正确,您可能需要执行
sort -t , -k 2
. - 如果您需要考虑 BLAH 的不同值,您需要 GNU awk (感谢调用
substr
)。否则,您可以终止该substr
调用,并且该脚本将在任何 posix awk 上运行。
答案2
这比我想象的要花更多的时间,但下面的脚本可以完成这项工作。
#!/bin/bash
str=" Sun Aug 21 2016 03:00:00, BLAH Mon Aug 22 2016 03:54:00, BLAH"
str+=" Tue Aug 23 2016 04:22:11, BLAH Thu Aug 25 2016 05:00:00, BLAH"
IFS='H' read -r -a inputArray <<< "$str"
days=(SunMon MonTue TueWed WedThu ThuFri FriSat SatSun)
count=1
found=0
lastOne=""
finalCount=0
for entry in "${inputArray[@]}"; do
thisOne="${entry:1:3}"
test="$lastOne$thisOne"
for pair in "${days[@]}"; do
if [ "$test" == "$pair" ]; then
((++count, ++found))
fi
done
if [ ! $found ]; then count=1; else found=0; fi
if [ $count -gt $finalCount ]; then
finalCount=$count
fi
lastOne=$thisOne
done
echo "There were $finalCount BLAHs in a row."