2014-01-10 2 views
0

while 루프 내에서 서로 다른 두 문자열의 첫 번째 인스턴스를 찾는 가장 쉬운 방법은 무엇입니까? 두 문자열에 대한 즉석에서 로그를 검색 중이며 문자열의 순서는 필수적이지 않으며 언제든지 발생할 수 있습니다. 그러나 때로는 로그의 아래쪽에 동일한 문자열의 인스턴스가 추가되기도하므로 두 문자열의 첫 번째 인스턴스 만 수집하고 필요한 타임 스탬프를 수집하기를 원합니다. 이 (정규식) 트리거 올바른 문자열과 일치 할 때 스크립트가 성공적으로 작품을 좋아하고,while 루프 내에서 두 문자열 일치의 첫 번째 인스턴스

while(<$log_DUT>) { 
    $fh_DUT->print($_); 
    if (m/<\sOPERATOR\s\{[^,]+,\s[^,]+,\s\d+\}\s\[SUB0\]/){ 
     $dsub1found = 1; 
     open (DUTfFILE, ">>", "$TimeDutfsub1"); 
     print DUTfFILE DUTcurTime(),"\n"; 
     close (DUTfFILE); 
    } 

    if (m/<\sOPERATOR\s\{[^,]+,\s[^,]+,\s\d+\}\s\[SUB1\]/){ 
     $dsub2found = 1; 
     open (DUTfFILE, ">>", "$TimeDutfsub2"); 
     print DUTfFILE DUTcurTime(),"\n"; 
     close (DUTfFILE); 
    } 
    last if ($dsub1found & $dsub2found == 1); 
} 

지금까지 IS이 코드는 ... 그러나 그것은 동일한 문자열의 추가 인스턴스를 캡처 계속, 타임 스탬프를 캡처해야 루프는 여전히 두 번째 정규식 문자열을 기다려야합니다 (반대의 경우도 마찬가지입니다).

예를 들어 $ dsub1found! = 1 인 경우 if 문을 시작했지만 행운이 없으면 문자열이 발견되지 않고 스크립트가 시간 초과되었습니다.

다른 걱정거리는 동일한 while 루프에서 두 개의 문자열 검색을하는 것이 현명한 방법인지 여부에 관한 것입니다. 이 글을 읽고에 대한

덕분에, MikG

답변

3
while (<$log_DUT>) { 
    $fh_DUT->print($_); 
    if (!$dsub1found && m/<\sOPERATOR\s\{[^,]+,\s[^,]+,\s\d+\}\s\[SUB0\]/){ 
     ... 
    } 

    if (!$dsub2found && m/<\sOPERATOR\s\{[^,]+,\s[^,]+,\s\d+\}\s\[SUB1\]/){ 
     ... 
    } 

    last if $dsub1found && $dsub2found; 
} 

왜 모든 반복이 필요합니까?

my @TimeDutfsub = ($TimeDutfsub1, $TimeDutfsub2); 

my @dsubfound; 
while (keys(%seen) != 2 && ($_ = <$log_DUT>)) { 
    $fh_DUT->print($_); 
    if (my ($n) = m/<\sOPERATOR\s\{[^,]+,\s[^,]+,\s\d+\}\s\[SUB([01])\]/){ 
     if (!$dsubfound[$n]++) { 
      open(my $DUTfFILE, ">>", $TimeDutfsub[$n]) or die $!; 
      print $DUTfFILE DUTcurTime(),"\n"; 
     } 
    } 
} 
+0

이케 가미 덕분에, 이것은 제가 생각했던 것과 같습니다. 이 반복은 순수하게 Perl의 초보자이기 때문에 가능하지만 결국 연습을 통해 나중에 스크립트를 단축하여 효율적으로 만들 수있게됩니다. 그러나 그것이 그렇듯이 지금은 반복적 인 형식으로 작업하는 것이 내 이해에 더 분명합니다. 나는 단축 스크립트를 시도했지만 '$ TimeDutfsub $ n'은 '$ TimeDutfsub'가 정의가 필요하다는 것을 의미합니다. – MikG

+0

Re "반복은 순수하게 Perl을 사용하는 초보자이기 때문에입니다."미안하지만, 나는 수사학 적이라는 의미였습니다. . 나는 "그 반복을 모두 없애기는 쉬울 것입니다." – ikegami

+0

Re'$ TimeDutfsub','$'의 앞부분에 눈치 채지 못했는데,'TimeDutfsub1'과'TimeDutfsub2'라는 파일을 만들었다 고 생각했습니다. 배열을 사용해야한다. my @TimeDutfsub = (..., ...);''$ TimeDutfsub [$ n]'을 사용한다. – ikegami

2

글쎄, 우선 당신은 (두 개의 문 경우가 있다는 것을, 사실에 기초) while 루프 중 하나 interation에서 두 문자열을 일치시켜야하는 것 . 이 경우, 반복 할 때마다 $ dsub1found 및 $ dsub2found를 0으로 초기화해야합니다.

두 번째로, '&'은 비트 단위이며 연산이므로 원하는 결과가 아닐 수 있습니다. 나는 당신이 '& &'을 의미한다고 가정합니다.

if ($dsub1found && $dsub2found == 1) 

이 수표, $의 dsub1found는 사실 그 두 변수의 초기 값은 충분하다 다음

if ($dsub1found && $dsub2found) 

, 0 인 경우 $ dsub2found 1. 동일한 경우. 당신이 둘 다 1로 동일 할 그러나 경우에, 당신은해야합니다 : 그것은 여전히 ​​작동하지 않을 경우

if ($dsub1found == 1 and $dsub2found == 1) 

, 디버깅 목적으로 while 루프의 끝에서 $의 dsubfound 변수 값을 인쇄 해보십시오 . 어쩌면 입력을 프린트하여 무슨 일이 일어나고 있는지 볼 수도 있습니다.

2

우선 당신이 그것을

을 계획하지 않는 한 당신은 운이 말을 당신의 모든

(1 & 1) = 1 만 올바르게 1에 대해 확인하는 때문에 문이 작동 할 필요가있는 경우

및 & 이상 ==의 경우에도 우선 순위

는 $ A(당신

작동 343,488,$ B == 1) => ($ A &의 ($ B == 1))

케이스 (1) A = 0, B = 0 => (0 & (0 == 1)) => (0 & 0) => (= 1, B = 0)

거짓 케이스 2 = 0> (0 & (1 == 1)) => (0 & 1) => (0) 거짓

= = 1, B = 0, B =

케이스 3 = 1> (1 & (0 == 1)) => (1 & 0) => (0)

거짓 케이스 4 = 1> (1(1 == 1) => (1 &) => (1) 참

테스트가 저에게 효과가있는 것 같습니다. 내 파일 입력이 "새 것에서 1d2 ba"였습니다. 라인과 당신이 어딘가에 당신의 dsub1found 및 dsub2found 값으로 재생하는 경우는 첫 번째 인스턴스 만

while (<$FH>) 
{ 
    if ($_ =~ /a/) 
    { 
    $flag_a=1; 
    print $_ ; 
    } 
    if ($_ =~ /b/) 
    { 
    $flag_b=1; 
    print $_ ; 
    } 

    last if($flag_a & $flag_b ==1); 

} 

확인을위한 AB를 인쇄하기 때문에 당신의 상태가 아주 많이 의존이 켜져있는 경우. 위의 조언을 사용하고 ID 조건을 강력하게 만들 것을 제안합니다.

관련 문제