2016-11-15 5 views
0

현재 GAWK 스크립트는 구문 파일을 가져 와서 정규식 패턴의 배열을 만든 다음 각 행을 \ t 문자로 분할하고 각 행의 처음 10 열을 반복 한 다음 하나 이상의 구문을 포함하는지 확인합니다 패턴 배열에서, 그럴 경우 선을 건너 뛰고 문서로 인쇄하지 않습니다.FOR에서의 GAWK concat 변수

문제 : 구문 파일은 반복 하중을 생성 크고 스크립트가 매우 느린하게

때문입니다.

(700 패턴 x 10 열 (탭 \ t로 구분)) x 1000 행.

솔루션 :

내가 처음 10 열을 CONCAT 싶습니다 속도를 향상시키고, 전체 문자열이 적어도 하나의 패턴이 포함되어 있는지 확인합니다. FOR 루프에서 줄을 연결하는 방법을 알아낼 수 없습니다.

근무 예 :

gawk 'BEGIN{ 
FS=" *\t *"; 
IGNORECASE=1; 

while(getline a < "'$phpath'") PATS["^.*"a".*$"] 
} 

{ 
    ok=1; 
    for(i=1;i<=10;i++){ 
     for(p in PATS){ 
      if($i ~ p){ 
      ok=0 
      } 
     } 
    } 

} 
ok {print}' "$f" > "$newPath$filename" 

내 시도 : AWK에서

gawk 'BEGIN{ 
    FS=" *\t *"; 
    IGNORECASE=1; 

    while(getline a < "'$phpath'") PATS["^.*"a".*$"] 
    } 

    { 
     phrase=""; 
     space=" "; 
     ok=1; 

     for(i=1;i<=10;i++){ 
      phrase = $space $phrase $i 
     } 

     for(p in PATS){ 
      if($phrase ~ p){ 
       ok=0 
      } 
     } 

    } ok {print}' "$f" > "$newPath$filename" 

답변

1

, 당신은 $x는 의미 역 참조 연산자처럼 $을 사용하여 "나에게 그 숫자 컬럼의 값을 제공 변수에 있음 x "

처음 10 개 콜 문자열로 MNS :

gawk -v patternfile="$phpath" ' 
    BEGIN { 
     FS = " *\t *" 
     IGNORECASE = 1 
     while ((getline a < patternfile) > 0) 
      PATS["^.*"a".*$"] 
    } 
    { 
     line = $0 
     NF = 10   # this truncates the current record to 10 fields 
     ok = 1 
     for (p in PATS) 
      if ($0 ~ p) { 
       ok = 0 
       break 
      } 
     if (ok) 
      print line 
    } 
' "$f" > "$newPath$filename" 
+0

매우 명확한 설명과 제안 된 솔루션에 감사드립니다. 코드가 훨씬 가볍게 보입니다. 제안 된 솔루션에서 패턴을 반복 할 때 휴식이 필요합니까? –

+0

죄송합니다. 업데이트되었습니다. –

+1

getline은'-1'을 반환하기 때문에 patternfile을 읽는 중 오류가 발생하면 무한 루프가됩니다. 'while ((getline a ) 0)'이 필요하다. http://awk.freeshell.org/AllAboutGetline을 보라. 배열을 채우는 대신 patternfile에서 분리 된'|'문자열을 만들어서 루프없이 비교할 수 있습니다. –

0
:

for (i=1; i<=10; i++) { 
     # not this => phrase = $space $phrase $i 
     phrase = space phrase $i 
    } 

for (p in PATS) { 
     if (phrase ~ p) { # <= no $ 
      ok = 0 
      break   # no match, so break the loop early 
     } 
    } 

AWK는 C와 같은 변수를 사용은


당신이 시도 할 수 쉘이나 펄을 좋아하지

이것은 귀하의 질문에 대한 답변이 아니지만 너의 문제에.

귀하의 문제는 성능에 대해 알고 있습니다.

중요한 문제 중 하나가 RegEx를 사용하고 있다는 것입니다. 내 요점을 설명해 줄께. AWK에서는 다음과 같이 정규 표현식을 사용하여 작업 할 때 :/MyRegExp /, RegEx의 컴파일 된 버전을 사용하므로 일치 할 때마다 확인 만하면되지만 RegEx를 사용하면 다음과 같이됩니다. "MyRegExp", 이것은 문자열이 일치하는지 확인하려고 할 때마다 컴파일됩니다.

RegEx를 실제로 확인 하시겠습니까? 어쩌면 당신은 아니며 함수 '인덱스'가 당신에게 충분할 것입니다.

왜 스크립트를 작성하여 실행하지 않으시겠습니까? 두 번째 파일의 모든 줄을로드 된 패턴과 대조하여 다음과 같은 스크립트를 작성하십시오.

/pattern1/{ 
    print 
    next 
} 
/pattern2/{ 
    print 
    next 
} 
/pattern3/{ 
    print 
    next 
} 
... 
... 

그런 다음 두 번째 파일로 실행하십시오. 어쨌든 도움이되기를 바랍니다.

0
while(getline a < "'$phpath'") PATS["^.*"a".*$"] 

^.*"a".*$a는 동일하다. 패턴을 반복하는 대신 OR 조건을 직접 |으로 지정할 수 있습니다. 당신의 입력 파일이 RE가 every|good|boy|does|fine된다

every 
good 
boy 
does 
fine 

과 코드가

입니다
$0 ~ pattern { 
    for (i=1; i<=10; i++) { 
     if($i ~ pattern) { 
      print "$f" > "$newPath$filename" # what's $f? 
      break 
     } 
    } 
} 

로 감소 된 경우

는 먼저 전체 라인을 스캔 할 수 있습니다. 발견되면 처음 10 개 열을 반복합니다. 무조건 무조건 반복하는 것보다 빠릅니다.

+0

열에 정확한 구문이 포함되어 있지 않기 때문에 패턴이 필요합니다. 예 : '내 구절 테스트, 테스트, 테스트, 테스트, 테스트, 테스트' 'my phrase'를 캡처하려면 정규식이 필요합니다. –