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 조각은 , , , 가 인쇄됩니다 .a2
b
c
d
grep -A3
a1
a2
b
c
a2
b
c
print
a1
a2
b
c