file1에서 패턴을 읽고 file2에서 반복적으로 검색합니다.

file1에서 패턴을 읽고 file2에서 반복적으로 검색합니다.

file1에서 패턴을 읽고 file2를 반복하고 검색하여 일치하는 줄과 3줄을 인쇄한 다음 file3에 인쇄하고 싶습니다.

지금 나는하고 있습니다 :

cat file1 | while read line; do awk '/$line/ {for(i=1; i<=3; i++) {getline; print}}' file2 > file3 ; done

이를 수행하는 더 효율적인 방법이 있습니까? 내 irl 파일은 엄청납니다(~30GB).

답변1

각 패턴에 대해 파일을 한 번씩 스캔할 수 있습니다. 특히 파일이 캐시에 맞지 않기 때문에 파일을 한 번만 찾아보는 것이 훨씬 빠릅니다.

귀하의 예제 코드는 실제로 file1. 단일 파일에 모든 일치 항목이 필요한 경우 패턴이 "OR" 연산자로 연결되는 것과 같습니다.

awk '
    BEGIN {
        while (getline <"file1") pattern = pattern "|" $0;
        pattern = substr(pattern, 2);
    }
    match($0, pattern) {for(i=1; i<=3; i++) {getline; print}}
' file2 > file3

또한 이는 일치하는 줄을 인쇄하지 않고 다음 세 줄만 인쇄한다는 점에 유의하세요. 다음 세 줄 앞에 일치하는 줄을 인쇄하려면 루프 print;앞에 추가 항목을 추가 해야 합니다 for.

실제로 다음 세 줄 앞에 일치하는 줄을 인쇄하고 grep명령이 해당 -A매개변수를 지원하는 경우 해당 매개변수를 사용해야 합니다. grep과 같은 특수 프로그램은 awk와 같은 해석 언어보다 빠른 경우가 많습니다. 추가 보너스로 명령이 훨씬 간단합니다.

grep -A -E -f file1 file2 >file3

grep이 느린 경우 멀티바이트 로케일의 GNU grep에 결함이 있기 때문일 수 있습니다. 때로는 파일이나 패턴에 멀티바이트 문자가 포함되어 있지 않더라도 매우 느릴 수 있습니다. ASCII가 아닌 문자와 일치시키기 위해 문자 클래스를 사용하지 않는 경우(예: [[:alpha:]]모든 유니코드 문자와 일치시키기 위해 문자 클래스를 사용하지 않는 경우) 단일 바이트 로케일에서 grep을 실행하십시오.

LC_ALL=C grep -A3 -E -f file1 file2 >file3

grep의 출력은 awk 조각과 정확히 동일하지 않습니다. 왜냐하면 이전 줄로 인해 인쇄되는 줄 중 하나에서 패턴이 발견되면 다르게 동작하기 때문입니다. 예를 들어, 모드가 이고 a행이 , , 이면 , 가 인쇄되고 , 위 a1의 awk 조각 은 , 추가 인쇄 가 있는 awk 조각은 , , , 가 인쇄됩니다 .a2bcdgrep -A3a1a2bca2bcprinta1a2bc

관련 정보