在文件中的两个模式之间Grep

时间:2016-01-23 23:43:57

标签: bash awk grep

实施例

Date & Time : 2016-01-23 02:00:00
abc
abc
abc
Date & Time : 2016-01-24 03:00:00
abc
abc
abc
abc
Date & Time : 2016-01-25 05:00:00

我想计算两种模式(比如2016-01-23和01-24)之间的abc总数,然后(比如2016-01-24到2016-01-26)。

4 个答案:

答案 0 :(得分:5)

一个小状态机:

awk '/Date & Time/ {if (n) print n; n=0; next} {n++}' file

在两个特定日期之间

awk -v d1="2016-01-24" -v d2="2016-01-26" '
    /Date & Time/ {if ($5 >= d1) counting = 1; else if ($5 >= d2) exit; next}
    counting {count++}
    END {print count}
' file

答案 1 :(得分:4)

$ grep -zo 'Date & Time : 2016-01-23 02:00:00.*Date & Time : 2016-01-24 03:00:00' infile |
> grep -zo 'abc' | wc -l
3
$ grep -zo 'Date & Time : 2016-01-24 03:00:00.*Date & Time : 2016-01-25 05:00:00' infile |
> grep -zo 'abc' | wc -l
4

将文件视为二进制文件以忽略换行符(-z)并仅保留匹配的内容(-o),然后匹配所有abc次出现并计算它们(wc -l )。

以稍微好一点的脚本格式:

$ pattern1='Date & Time : 2016-01-23 02:00:00'
$ pattern2='Date & Time : 2016-01-24 03:00:00'
$ grep -zo "$pattern1"'.*'"$pattern2" infile | grep -zo 'abc' | wc -l
3

使用sed的解决方案(使用与上面相同的模式变量):

$ sed -n "/$pattern1/,/$pattern2/{/abc/p}" infile | wc -l
3

这假设每行永远不会有多个abc。如果有:

sed -n "/$pattern1/,/$pattern2/p" infile | grep -o 'abc' | wc -l

答案 2 :(得分:3)

有很多方法可以做到这一点。这是一个awk示例,使用简单状态指示何时找到匹配条件(state = 1)

BEGIN { state = 0; count = 0; }
/^Date \& Time : 2016-01-23 02:00:00$/ { state = 1; next; }
/^Date \& Time : 2016-01-24 03:00:00$/ {state = 2; next; }
/^abc$/ { if (state == 1) count++; }
END { print "Found abc " count " times."

希望这会有所帮助。我假设您的abc独自在一条线上,并根据需要进行自定义。

答案 3 :(得分:1)

当然,Perl可以做到。

假设:

$ echo "$tgt" 
Date & Time : 2016-01-23 02:00:00
abc
abc
abc
Date & Time : 2016-01-24 03:00:00
abc
abc
abc
abc
Date & Time : 2016-01-25 05:00:00

Perl:

$ echo "$tgt" | perl -0777 -lne 'while(/(^Date & Time :[\d\-: ]+)\s+(\S.*?)(?=^Date & Time :[\d\-: ]+)/gsm){$x=$2=~tr/\n//; print "$1 $x lines\n"}'
Date & Time : 2016-01-23 02:00:00 3 lines
Date & Time : 2016-01-24 03:00:00 4 lines