문제

나는 로그 파일의 구문 분석이 필요한 프로젝트를 진행하고 있습니다.다음과 같은 그룹 메시지를 받는 빠른 알고리즘을 찾고 있습니다.

P1의 온도는 35F입니다.

P1의 온도는 40F입니다.

P3의 온도는 35F입니다.

로거가 중지되었습니다.

로거가 시작되었습니다.

P1의 온도는 40F입니다.

printf() 형식으로 무언가를 출력합니다.

"The temperature at P%d is %dF.", Int1, Int2" 
{(1,35), (1, 40), (3, 35), (1,40)}

알고리즘은 메시지 그룹의 거의 모든 데이터 로드를 인식할 수 있을 만큼 일반적이어야 합니다.

이런 기술을 검색해봤는데, 검색해야 할 정확한 용어조차 모르겠어요.

도움이 되었습니까?

해결책

개요:

순진한!! 알고리즘은 열 단위 방식으로 단어의 빈도를 추적합니다. 여기서 각 줄은 구분 기호를 사용하여 열로 분리될 수 있다고 가정할 수 있습니다.

입력 예:

개는 달 위로 뛰어올랐다
고양이가 달 위로 뛰어올랐어요
달이 달 위로 뛰어올랐다
차가 달 위로 뛰어올랐다

주파수:

Column 1: {The: 4}
Column 2: {car: 1, cat: 1, dog: 1, moon: 1}
Column 3: {jumped: 4}
Column 4: {over: 4}
Column 5: {the: 4}
Column 6: {moon: 4}

전체 필드 수를 기준으로 그룹화하여 이러한 빈도 목록을 더 분할할 수 있지만 이 간단하고 편리한 예에서는 고정된 수의 필드(6)로만 작업합니다.

다음 단계는 이러한 주파수 목록을 생성한 라인을 반복하는 것이므로 첫 번째 예를 살펴보겠습니다.

  1. 그만큼:몇 가지 손쉬운 기준을 충족하고 알고리즘은 그것이 정적이어야 한다고 결정합니다.
  2. :나머지 주파수 목록을 기준으로 보면 정적인 것으로 보이지 않으므로 정적인 텍스트와 달리 동적이어야 합니다.우리는 미리 정의된 몇 가지 정규 표현식을 반복해서 살펴봅니다. /[a-z]+/i.
  3. ~ 위에:#1과 동일한 거래;정적이므로 그대로 두십시오.
  4. 그만큼:#1과 동일한 거래;정적이므로 그대로 두십시오.
  5. :#1과 동일한 거래;정적이므로 그대로 두십시오.

따라서 첫 번째 줄부터 다음 정규 표현식을 구성할 수 있습니다.

/The ([a-z]+?) jumps over the moon/

고려사항:

  • 빈도 목록이 전체 데이터의 충분한 샘플링이 될 것이라는 확신이 있는 한 첫 번째 패스에서 문서의 일부 또는 전체를 스캔하도록 선택할 수 있습니다.

  • 거짓 긍정이 결과에 나타날 수 있으며, 정적 필드와 동적 필드 사이 또는 일부 인간 사후 처리 간의 최상의 임계값을 제공하는 것은 필터링 알고리즘(손 흔들기)에 달려 있습니다.

  • 전반적인 아이디어는 아마도 좋은 것일 수 있지만 실제 구현은 확실히 이 알고리즘의 속도와 효율성에 영향을 미칠 것입니다.

다른 팁

나는 당신이 fscanf()와 sscanf()를 간과하고 놓쳤을 것이라고 생각합니다.fprintf()와 sprintf()의 반대입니다.

모든 훌륭한 제안에 감사드립니다.크리스, 맞아요.모든 종류의 텍스트를 정규화하기 위한 일반적인 솔루션을 찾고 있습니다.문제의 해결책은 두 개 이상의 유사한 문자열에서 동적으로 패턴을 찾는 것으로 요약됩니다.이전 두 요소를 기반으로 세트의 다음 요소를 예측하는 것과 거의 같습니다.

1:에베레스트는 높이가 30000피트다

2:K2의 높이는 28000피트입니다

=> 패턴은 무엇입니까?=> 답:

[이름] 키는 [숫자]피트입니다

이제 텍스트 파일에는 수백만 개의 줄과 수천 개의 패턴이 포함될 수 있습니다.나는 파일을 매우 빠르게 구문 분석하고, 패턴을 찾고, 각 패턴과 연관된 데이터 세트를 수집하고 싶습니다.

메시지 문자열의 패턴을 표현하기 위해 높은 수준의 의미 체계 해시를 만드는 방법을 생각했습니다.나는 토크나이저를 사용하고 각 토큰 유형에 특정 "가중치"를 부여합니다.그런 다음 해시를 그룹화하고 유사성을 평가합니다.그룹화가 완료되면 데이터 세트를 수집합니다.

나는 바퀴를 재발명할 필요가 없고 이미 존재하는 것을 재사용할 수 있기를 바랐습니다.

클라우스

이는 수행하려는 작업에 따라 다릅니다. 목표가 sprintf() 입력을 빠르게 생성하는 것이라면 이것이 작동합니다.데이터를 구문 분석하려는 경우 정규 표현식도 수행할 수 있습니다.

단순히 임의의 입력을 받아서 그로부터 원하는 데이터가 무엇인지 추측하고 원하는 출력을 생성할 수 있는 도구는 찾지 못할 것입니다.그것은 나에게 강력한 AI처럼 들립니다.

숫자를 인식하기 위해서라도 이와 같은 것을 생산하는 것은 정말 까다롭습니다.예를 들어 "123.456"은 숫자 1개인가요, 아니면 2개인가요?이 "123,456"은 어떻습니까?"35F"는 10진수이고 'F'입니까, 아니면 16진수 값 0x35F입니까?필요한 방식으로 구문 분석할 수 있는 무언가를 구축해야 합니다.정규식을 사용하여 이를 수행할 수 있습니다. 또는 다음을 사용하여 수행할 수 있습니다. sscanf, 또는 다른 방법으로 수행할 수 있지만 사용자 정의 항목을 작성해야 합니다.

그러나 기본 정규식을 사용하면 이 작업을 직접 수행할 수 있습니다.마술은 아니지만 그렇게 많은 작업은 아닙니다.다음과 같은 기능은 관심 있는 줄을 구문 분석하고 통합합니다(Perl).

my @vals = ();
while (defined(my $line = <>))
{
    if ($line =~ /The temperature at P(\d*) is (\d*)F./)
    {
        push(@vals, "($1,$2)");
    }
}
print "The temperature at P%d is %dF. {";
for (my $i = 0; $i < @vals; $i++)
{
    print $vals[$i];
    if ($i < @vals - 1)
    {
        print ",";
    }
}
print "}\n";

이것의 출력은 isL

The temperature at P%d is %dF. {(1,35),(1,40),(3,35),(1,40)}

구문 분석해야 하는 각 유형의 줄에 대해 비슷한 작업을 수행할 수 있습니다.각각을 사용자 정의 코딩하는 대신 파일에서 이러한 정규식을 읽을 수도 있습니다.

이를 수행하는 특정 도구를 모르겠습니다.해결해야 할 비슷한 문제가 생겼을 때 내가 한 일은 줄과 일치하는 정규식을 추측하는 것이었습니다.

그런 다음 파일을 처리하고 일치하지 않는 줄만 표시했습니다.선이 일치하지 않으면 패턴이 잘못되었음을 의미하므로 수정하거나 다른 패턴을 추가해야 합니다.

약 한 시간의 작업 끝에 10000개 이상의 라인과 일치하는 ~20개의 패턴을 찾는 데 성공했습니다.

귀하의 경우 먼저 하나의 패턴이 다음과 같다고 "추측"할 수 있습니다. "The temperature at P[1-3] is [0-9]{2}F.".일치하는 줄을 제거하여 파일을 다시 처리하면 "만"이 남습니다.

로거가 중지되었습니다.

로거가 시작되었습니다.

그러면 다음과 일치시킬 수 있습니다 "Logger (.+).".

그런 다음 패턴을 구체화하고 전체 로그와 일치하는 새로운 패턴을 찾을 수 있습니다.

@남자:나는 그 질문이 실제로 로그 파일의 패턴을 인식하고 적절한 형식 문자열과 데이터를 자동으로 "추측"하는 알고리즘과 관련이 있다고 생각합니다.그만큼 *scanf 가족은 스스로 그렇게 할 수 없으며, 먼저 패턴을 인식한 후에만 도움이 될 수 있습니다.

@데릭 파크:글쎄, 심지어 강력한 AI조차도 그것이 올바른 대답을 가지고 있는지 확신할 수 없었습니다.

아마도 압축과 유사한 메커니즘을 사용할 수 있습니다.

  1. 크고 빈번한 하위 문자열 찾기
  2. 크고 빈번한 하위 문자열 패턴을 찾습니다.(즉.[패턴:1] [정크] [패턴:2])

고려해야 할 또 다른 항목은 라인을 그룹화하는 것입니다. 편집 거리.유사한 라인을 그룹화하면 문제가 그룹당 하나의 패턴 청크로 분할되어야 합니다.

사실 이 글을 쓰게 된다면 온 세상에 알리다, 우리 중 많은 사람들이 이 도구를 좋아할 것 같아요!

@앤더스

글쎄, 심지어 강력한 AI조차도 그것이 올바른 대답을 가지고 있는지 확신할 수 없었습니다.

충분히 강한 AI가 가능하다고 생각했는데 대개 문맥에서 정답을 찾아보세요.예를 들어Strong AI는 이 맥락에서 "35F"가 16진수가 아닌 온도임을 인식할 수 있습니다.아무리 강한 AI라도 대답하지 못하는 경우가 분명히 있습니다.하지만 인간이 대답할 수 없는 경우도 마찬가지입니다(가정). 매우 강력한 AI).

물론 우리에겐 강력한 AI가 없기 때문에 별 문제가 되지 않습니다.:)

http://www.logparser.com 꽤 활발해 보이는 IIS 포럼으로 전달합니다.이것은 Gabriele Giuseppini의 "Log Parser Toolkit"의 공식 사이트입니다.실제로 이 도구를 사용한 적은 없지만 Amazon Marketplace에서 저렴한 책 사본을 구입했습니다. 현재 사본 가격은 16달러입니다.페이지를 넘기는 데 데드 트리 인터페이스보다 나은 것은 없습니다.

이 포럼을 살펴보면서 저는 이전에 "MS Log Parser, Log Parser Lizard를 위한 새로운 GUI 도구"에 대해 들어본 적이 없습니다. http://www.lizardl.com/.

물론 핵심 문제는 문법의 복잡성입니다.일반적으로 사용되는 모든 종류의 로그 파서를 사용하려면 스캔하려는 대상이 무엇인지 정확히 알아야 하며 이에 대한 BNF를 작성할 수 있습니다.수년 전에 나는 Aho-and-Ullman의 "Dragon Book"을 기반으로 한 강좌를 수강했는데, LALR 기술을 철저하게 이해하면 CFG가 있는 경우 최적의 속도를 제공할 수 있습니다.

반면에 AI와 같은 것에 도달할 가능성이 있는 것 같습니다. 이는 완전히 다른 복잡성의 순서입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top