
다른 파일의 입력을 사용하여 로그 파일의 특정 줄을 파악하고 싶습니다. 나는 그것을 하기 위해 이 작은 명령을 사용하고 있습니다:
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.log
result.txt
input_strings.txt
service.log
service.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
i
0부터 시작하여 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
이는 간단해야 합니다.