5분 이상 egrep 정규 표현식

5분 이상 egrep 정규 표현식

내 텍스트 파일에 다음과 같은 시간 형식이 있습니다.

       `1` equals one second.
    `5|01` equals five minutes and one seconds.
   `13|01` equals thirteen minutes and one seconds.
`21|12|01` equals 21 hours, 12 minutes, and 1 seconds.

5분보다 긴 항목을 egrep해야 합니다. 다음 정규식을 사용하고 있지만 다음과 같은 시간을 제외하기 때문에 작동하지 않습니다 13|00.

'[[:space:]0-9][[:space:]0-9][[:space:]|][[:space:]0-9][[:space:]6-9][|][0-9][0-9]'

예는 다음과 같습니다.

 lite on       1
 lite on      01
 lite on    5|22
 lite on   23|14
 lite on 1|14|23

답변1

공백(나중에 직접 채울 수 있음)과 앞에 오는 0(다시 한번)을 무시하세요.

[5-9]\|[0-9]+
[1-9][0-9]\|[0-9]+
[0-9]+\|[0-9]+\|[0-9]+

범위 내의 시간 동안

[5,10) minutes
[10,99) minutes
1+ hours

각기.

(...|...)따라서 시작과 끝 부분에 충분한 고정이 있는 일치하는 그룹에 참여하십시오 (따라서 14|59또는 일치하지 않음 1|00|00).

이것은

grep -E 'on +([5-9]\|[0-9]+|[1-9][0-9]\|[0-9]+|[0-9]+\|[0-9]+\|[0-9]+) *$'

초는 세 가지 정규식 모두에 공통되므로 이를 조금 단순화할 수 있습니다.

grep -E 'on +([5-9]|[1-9][0-9]|[0-9]+\|[0-9]+)\|[0-9]+ *$'

답변2

이것은 작동합니다:

grep -E '( [0-9]{1,2}\|[0-9]{1,2}\|[0-9][1-9] )|( [0-9][0-9]\|[0-9]{2,2} )|( [5-9]\|[0-9][1-9] )|( [6-9]\|[0-9][0-9] )' <file>

기본적으로 '로 캡슐화되고 '로 구분된 4개의 패턴을 생성합니다 (). |동작 은 정규식 |과 동일합니다.or

이런 {1,2}부분은 1-2 instances of preceding pattern정말 [0-9]{1,2}의미가 있어요1-2 instances of 0-9

or그런 다음 구문을 통해 가능한 모든 숫자 조합에 대한 기본 테스트 사례를 만듭니다.

답변3

grep정규식은 패턴 일치에는 좋지만 값 일치에는 좋지 않습니다 . 할 수도 있지만 망치를 드라이버로 사용합니다. 기술적으로는 작동하지만 지저분하고 비효율적입니다.

그래서 대신:

#!/usr/bin/env perl

use strict;
use warnings;

while (<DATA>) {
    my @numbers = m/(\d+)/g;
    my $seconds = pop(@numbers);
    $seconds += ( pop(@numbers) // 0 ) * 60;  #second digit minutes -> seconds
    $seconds
        += ( pop(@numbers) // 0 ) * 60 * 60;  #third digit, hours  -> seconds;
    print if $seconds > 300;
}

__DATA__
 lite on       1
 lite on      01
 lite on    5|22
 lite on   23|14
 lite on 1|14|23

이것은 다음을 인쇄합니다:

 lite on    5|22
 lite on   23|14
 lite on 1|14|23

다음과 같이 단순화할 수 있습니다.

perl -ne 'for ( m/(\d+)/g ) { $t *= 60; $t += $_ }; print if $t > 300;'

보너스 포인트의 경우 - 별 어려움 없이 상당히 임의적인 유효성 검사 기준을 처리하며 언젠가 다른 값을 찾기로 결정한 경우 많은 수정이 필요하지 않습니다.

그러나 위의 작업은 다음과 같이 작동합니다.

  • m/(\d+)/g-를 일치 항목으로 사용한다는 것은 g"하나 이상의 숫자"의 반복되는 인스턴스를 배열로 선택한다는 의미입니다. ( @numbers또는 두 번째 예의 for 루프에 있는 자체 포함 반복자와 같습니다).
  • 이 숫자 체인은 60을 곱하여 초로 변환합니다. (요일을 추가하면 잘 작동하지 않습니다!)
  • 그런 다음 숫자가 300보다 큰지 테스트합니다. 이는 초 단위로 5분입니다.

관련 정보