파일을 한 줄씩 읽고 파일의 마지막 위치를 기억합니다.

파일을 한 줄씩 읽고 파일의 마지막 위치를 기억합니다.

다른 파일의 입력을 사용하여 로그 파일의 특정 줄을 파악하고 싶습니다. 나는 그것을 하기 위해 이 작은 명령을 사용하고 있습니다:

while read line; do 
    grep "$line" service.log; 
done < input_strings.txt > result.txt

input_strings.txt약 50,000개의 문자열(한 줄에 하나씩)이 있습니다. 나는 현재 이 문자열 각각에 대해 거대한 service.log파일(대략 2,000,000줄)을 검색하고 있습니다.

첫 번째 문자열이 10,000 행에서 발견되고 input_strings.txt이 행이 내 항목에 기록된다고 가정합니다. 그 후 두 번째 문자열이 검색되지만 행 1부터 시작됩니다.service.logresult.txtinput_strings.txtservice.logservice.log

에서 첫 번째 항목의 마지막 줄을 찾는 것을 어떻게 기억합니까 service.log? 그러면 두 번째 검색 실행은 어디서 시작할 수 있나요?

답변1

일치 항목을 얻으려면 루프를 전혀 사용할 필요가 없습니다. 단일 명령을 사용하는 것이 훨씬 빠릅니다 grep.

grep -Ff input_strings service.log > results.txt

즉, 질문에 명시된 내용을 문자 그대로 수행하려면 변수를 사용하여 마지막 일치 항목이 발견된 행을 추적할 수 있습니다.

LINE_NUMBER=0
while read LINE; do

    # Search for the next match starting at the line number of the previous match
    MATCH="$(tail -n+${LINE_NUMBER} "service.log" | grep -n "${LINE}" | head -n1)";

    # Extract the line number from the match result
    LINE_NUMBER="${MATCH/:*/}";

    # Extract the matching string from the match result
    STRING="${x#*:}";

    # Output the matching string
    echo "${STRING}";

done < input_strings.txt > result.txt

답변2

첫 번째 키워드를 검색하고 그 일치 후에 다음 키워드 등을 계속 검색하고 일치 항목을 인쇄하려는 것 같습니다.

반면 keywords:

foo
bar

그리고 data:

bar 0
foo 1
bar 1
foo 2

awk이를 수행해야 하는 스크립트는 다음과 같습니다 (GNU awk로 테스트).

$ awk 'BEGIN {i = j = 0} NR==FNR { k[i++] = $0; next} 
       $0 ~ k[j] {j++; print $0} j >= i {exit}' keywords data 
foo 1
bar 1

i0부터 시작하여 j첫 번째 파일( NR==FNR현재 파일의 레코드/라인 번호를 표시된 총 라인 수와 비교) 중에 키워드를 배열로 수집합니다. 그런 다음 j:th 키워드를 일치시키고 j일치하면 인쇄하고 증가시킵니다. 키워드를 모두 찾은 후 종료합니다.

에서와 같이 grep여기의 키워드는 실제로 정규식 패턴이지만 awk여기서는 분명히 정규식입니다. 고정된 문자열을 검색하려면 index($0, key)대신 를 사용하세요 $0 ~ key.


또는 키워드를 로드하지 않고 시작하려면 다음을 수행하세요.

$ awk -vkeyfile=keywords 'BEGIN {getline key < keyfile } 
      $0 ~ key {print $0; if (!getline key < keyfile) exit;}' data
foo 1 
bar 1

이는 간단해야 합니다.

관련 정보