매우 큰 파일에 대해 아래 두 명령을 실행했습니다.
grep -E 'string1|string2' 151103*.log|grep 'string3' | grep string4
awk '/string1|string2/ && /string3/ && /string4/' 151103*.log
실행하는 데 거의 같은 시간이 걸렸습니다. 그러나 awk
일치하는 결과를 표시하는 것이 훨씬 빨랐습니다. grep
나 역시 같은 결과를 보여주었지만 결국에는 프로세스가 완료되었습니다.
awk
둘 다 프로세스를 완료하는 데 동일한 시간이 걸렸습니다. 및 에 대한 검색 이면의 논리를 알고 싶습니다 grep
.
왜 awk
더 빠르나요? 두 프로그램 모두 서로 다른 검색 논리를 갖고 있나요? 위 검색에서 문자열을 뒤섞으면 검색 속도에 차이가 있나요?
답변1
GNU는 grep
출력을 버퍼링하지만 GNU는 awk
그렇지 않습니다. 그리고 GNU를 사용하지 않고 awk
다른 변형을 사용하더라도 터미널에 인쇄하는 경우 여전히 라인 버퍼링되어 발생하는 각 \n
ewline에 대한 출력을 플러시하지만 grep
파이프에 쓰기 때문에 차단됩니다. 어쨌든 버퍼. GNU가 있는 경우 비교에 grep
사용하여 결과를 빠르게 확인할 수 있습니다. 거의 모든 일치 테스트(특히 GNU)에서 승리할 grep --line-buffered ... | grep ...
가능성이 높습니다 .grep
awk
grep
sed
원하는 것을 수행하는 방법은 다음과 같습니다 .
sed -ne'/string4/{/string3/s/string[12]/&/p;}' <in >out
답변2
grep 파이프라인은 grep
string4의 최종 결과가 일치할 때까지 아무 것도 출력할 수 없으며 이전 파이프 버퍼가 채워진 후에만 입력을 받습니다. 관련 질문 보기파이프 버퍼는 얼마나 큽니까?그리고파이프에서 버퍼링 끄기.
입력의 문자열 빈도에 따라 정적 검색을 먼저 배치하여 확장 정규식을 덜 살펴봄으로써 런타임의 차이를 확인할 수 있습니다.
답변3
귀하의 awk 예는 한 번에 전체 정규식 검색을 수행하는 것입니다. 각 입력 줄에 대해 첫 번째, 두 번째, 세 번째 정규 표현식이 발견되면 해당 줄이 인쇄되고 기본적으로 일치하는 줄 처리 시 출력이 즉시 표시됩니다.
grep 예제는 동일한 작업을 수행하기 위해 3가지 다른 grep 호출(각 정규식에 대해 하나씩)을 사용하지만 각 호출의 출력은 다음 호출의 입력이 됩니다. 즉, 다음 호출이 처리하기 전에 각각 완료해야 함을 의미합니다.
단일 1000행 파일이 있고 5행만 3개의 정규식과 모두 일치하는 경우 awk 명령은 5행을 처리한 후 6행을 처리하기 전에 출력을 제공합니다. 파이프로 연결된 grep 문과 비교해 보세요. grep의 첫 번째 호출은 5번째 줄과 첫 번째 정규식과 일치할 수 있는 다른 줄을 찾고, 입력의 1000번째(마지막) 줄을 처리한 후 해당 출력은 grep의 두 번째 호출에 대한 입력이 됩니다. grep의 두 번째 호출은 첫 번째 출력의 많은 행을 처리하고 첫 번째 및 두 번째 정규식과 모두 일치하는 행을 출력합니다. 그런 다음 이는 grep의 세 번째 호출에 대한 입력이 됩니다. grep의 세 번째 호출은 각 줄을 처리하므로 정규식과 일치하는 모든 줄을 출력합니다.
위의 예에서 grep의 최고 사례와 최악의 사례를 비교할 수 있습니다. 5행을 제외하고 정규식과 일치하는 행이 하나도 없으면 첫 번째 grep은 1000행을 처리하고 두 번째 grep은 1행을 처리합니다. 세 번째 grep은 1줄을 처리합니다. 출력이 있기 전에 1002줄을 처리합니다(최상의 경우). 모든 줄이 처음 두 개의 정규식과 일치하지만 단 한 줄만 세 번째 정규식과 일치하는 경우 파이프된 grep 구성은 5번째 줄에서 일치하는 항목을 찾고 일부 출력을 갖기 전에 1000 + 1000 줄 + 5 = 2005 줄을 처리합니다. 두 번째 grep 출력의 나머지 995개 라인을 계속 처리하지만 일치하는 항목이 없기 때문에 더 이상 출력이 표시되지 않습니다.
이를 각 줄에 대해 세 가지 정규식을 모두 동시에 확인하고 다섯 번째 줄을 처리한 후 출력을 제공하는 awk 명령과 비교해 보세요. 동시에 더 많은 파일을 검사하면 차이가 더 커집니다.
예를 들어, 위에서 수행한 것처럼 모든 파일에 대해 grep 명령을 동시에 실행하는 대신 출력이 더 빨리 표시되는지 비교해 보십시오(이론적으로는 그래야 하지만 결과는 파일 전체의 적중 분포에 따라 달라질 수 있습니다).
grep -E 'string1|string2' 151103*.log|grep 'string3' | grep string4
대신 다음과 같이 각 파일에 대해 일련의 grep 명령을 개별적으로 실행합니다.
for i in 151103*.log;
do grep -E 'string1|string2' $i |grep 'string3' | grep string4;
done
여전히 awk 문만큼 빠르게 출력이 생성되지는 않지만 차이를 볼 수 있습니다.
답변4
grep, awk 및 sed는 비슷한 작업에 사용될 수 있지만 각각의 장점과 단점이 있습니다.
Awk는 표 형식의 데이터나 계산 등을 수행해야 할 때 가장 잘 작동합니다.
Sed는 텍스트 교체에 탁월합니다.
Grep은 입력 데이터에서 행을 선택하는 데 가장 적합하므로 이 작업에서는 이것이 awk보다 빠를 것으로 예상했습니다. 아마도 3개의 grep 명령을 하나로 결합하면 그 내용을 보게 될 것입니다. 현재 grep은 세 번 시작해야 하고 두 번째와 세 번째는 첫 번째 입력을 기다려야 하기 때문에 불리한 상황에 있습니다. 결과가 지연되는 이유를 설명할 수 있습니다. 그것에 대해 확실하지 않지만.