2011-10-04 3 views
1
[2011-09-23 18:46:51:697 GMT+00:00][17B020C421B4BCC2CEBAD9C1B77CA413.http-8080-6][com.abc.actions.RegisterAction] INFO loggedOut #mouseclicked# userid=1 
[2011-09-24 19:46:53:697 GMT+00:00][47B020C421B4BCC2CEBAD9C1B77CA413.http-8080-6][com.abc.actions.RegisterAction] INFO loggedOut #mouseclicked# userid=12 
[2011-09-25 20:46:51:697 GMT+00:00][57B020C421B4BCC2CEBAD9C1B77CA413.http-8080-6][com.abc.actions.RegisterAction] INFO loggedin #mouseclicked# userid=23 
[2011-09-25 20:46:51:697 GMT+00:00][57B020C421B4BCC2CEBAD9C1B77CA413.http-8080-6][com.abc.actions.RegisterAction] DEBUG mouseclicked by userid=566 
[2011-09-25 20:56:56:697 GMT+00:00][77B020C421B4BCC2CEBAD9C1B77CA413.http-8080-6][com.abc.actions.RegisterAction] INFO loggedin #mouseclicked# userid=44 
[2011-09-26 22:48:55:697 GMT+00:00][87B020C421B4BCC2CEBAD9C1B77CA413.http-8080-6][com.abc.actions.RegisterAction] INFO loggedOut #mouseclicked# userid=55 

위의 파일에서 mouseclicked #가 24-9 월 11 일에서 25-9 월 11 일 (두 날짜 포함)의 날짜에 몇 번이나 발생했는지 알고 싶습니다.유닉스 grep 쿼리

위의 경우

이 명령은 나에게 3 반환해야합니다 :

가 어떻게이 경우 grep 명령을 사용할 수 있습니다 (참고가 #와 일치하지 않는 것으로 간주되지 않는다의 mouseClicked는 #을의 mouseClicked)?

+0

그렙은 라인으로 라인을 사용할 수 있습니다. 'mouseclicked '를 grep하여 그 결과를 시작으로 정렬 할 수는 있지만 아마도 다른 도구가 더 유용 할 것입니다 (Perl일까요?). –

답변

3

grep만으로는 일반적인 문제가 해결되지 않습니다. 특정 날짜 범위 내에있는 행을 인식 할 수 없습니다. (글쎄, 충분히 복잡한 정규 표현식을 사용하면 가능할 수 있지만, 관심있는 날짜 범위마다 정규 표현식이 상당히 다를 수 있습니다.)

특정 질문에 대해서는 다음과 같이 작동합니다.

egrep -c '^\[2011-09-(24|25).*#mouseclicked#' filename 

egrep| 연산자를 포함하여 더 강력한 정규 표현식을 지원합니다. -c 옵션은 행 자체를 인쇄하지 않고 일치하는 행의 수를 인쇄하도록 지시합니다.

9 월 30 일 오후 1 시부 터 10 월 2 일 오전 11 시까 지 줄을 원한다면 정규 표현식이 훨씬 더 복잡해지며이를 구성하는 데 상당한 노력이 필요할 것입니다.

이 작업을 많이 수행하려면이 파일에 사용 된 특정 날짜 형식을 사용하여 지정된 날짜 범위 (또는 날짜와 시간)에서 선을 추출하는 별도의 도구를 작성해야합니다. YYYY-MM-DD HH : MM : SS, ISO-8601은 탁월한 선택입니다.) 개인적으로 필자는 Perl에서 이러한 도구를 작성했습니다. 그런 다음 파일에서 도구를 실행하고 grep을 통해 출력을 파이프 할 수있었습니다.

편집 :

주석에 대한 응답으로

, grep이 날짜 범위, 단지 문자 시퀀스를 이해하지 못합니다. 1-oct-2010에서 1-dec-2011 범위의 모든 항목과 일치하는 복잡한 정규식을 작성할 수 있습니다. 여기에 (안 테스트) 내 시도입니다 :

egrep -c '^\[(2010-1.*|2011-(0.|10|11)|2011-12-01).*#mouseclicked#' filename 

이 여러 개인 부분 범위를 다루는 9 월 한 후 2011 년 10 월의 다음 월부터 11 2010 년 12 월, 1 월을 통해 10 월, 그리고 마지막으로 2011 년

12 월 (1)

그리고 앞서 말했듯이 다른 날짜 범위 (또는 더 나쁜 날짜와 시간)의 경우 텍스트 표현을 기반으로 원하는 시간 범위의 하위 범위와 일치하는 완전히 새로운 복잡한 정규 표현식을 작성해야합니다 , 날짜로서의 의미가 아닙니다.

그래서이 작업을 한 두 번 이상 수행하고 싶다면 이런 접근 방식을 고려하지 않는 것입니다.

Perl이나 Python과 같은 스크립팅 언어를 알고 계십니까? 그렇다면 실제로 타임 스탬프를 구문 분석하고 원하는 범위 내에있는 라인을 선택하는 스크립트를 작성하는 것이 그리 어렵지 않을 것입니다.

그런 도구가 이미 존재한다면 사실 전혀 놀랄 일이 아닙니다. (어디에서 찾을 수 있을지 모르겠습니다).

편집 2 : 여기

내가 함께 던졌다 펄 스크립트입니다 : 자리 시퀀스로,

#!/usr/bin/perl 

use strict; 
use warnings; 

die "Usage: $0 start end [file...]\n" if scalar @ARGV < 2; 
my $start = shift; 
my $end = shift; 
$start =~ s/\D//g; 
$end =~ s/\D//g; 
$end .= '99999999999999999999999999999'; 

print "start=\"$start\", end=\"$end\"\n"; 

while (<>) { 
    if (/^\[([^]]+)\]/) { 
     my $timestamp = $1; 
     $timestamp =~ s/\D//g; 
     if ($timestamp ge $start and $timestamp le $end) { 
      print; 
     } 
    } 
} 

그것은 파일의 지정된 시작 시간과 종료 시간뿐만 아니라, 타임 스탬프를 취급하고 문자열 비교 (숫자가 아님) 비교를 수행합니다. 시간대 정보를 무시합니다. CPAN의 시간 및 날짜 모듈 중 하나를 사용하면 더욱 정교해질 수 있습니다.

원래의 질문에 대해, 당신은 실행 것 :

this-perl-script 2011-09-24 2011-09-25 input-file | grep -c '#mouseclicked#' 
+0

위의 명령을 사용하여 1-oct-2010에서 1-dec-2011까지의 기간을 지정하려면 어떻게해야합니까? – Mike

0

나는 다음과 같이 시도 할 것입니다. grep | wc-l

grep은 문자열을 포함하는 항목을 필터링하고, wc -l은 grep이 출력하는 행 수를 계산합니다.

+0

'grep -c'가 더 간단합니다. –

1
cat filename | grep '^\[2011-09-2[45]' | grep mouseclicked | wc -l 

또는 더 간단을 : 날짜 제한이 조금 까다 롭습니다 있도록

grep '^\[2011-09-2[45]' filename | grep -c mouseclicked 
+2

'cat'과'wc -l' 둘 다 불필요합니다. 그리고'[''grep '은 문자 범위의 시작이라고 생각하지 않습니다. –

+0

에 동의 함 나는 처음 '[':-) 입력을 주셔서 감사합니다. –

+0

아니요, 당신은 첫 번째 [[ '; 나는 그랬다. –