일부 명령이나 스크립트가 grep보다 빠르게 한 파일에서 다른 파일의 줄을 뺄 수 있습니까?

일부 명령이나 스크립트가 grep보다 빠르게 한 파일에서 다른 파일의 줄을 뺄 수 있습니까?

주기적으로 실행하는 쉘 스크립트가 있는데 그 중 다음 부분으로 인해 속도가 느려집니다.

grep -v -f RemoveTheseGoodIPs.txt FromTheseShadyIPs.txt > RemainingBadIPs.txt

효과가있다. 출력을 제공하는 데 156초밖에 걸리지 않습니다. 나는 이해하기 쉽고 우아한 이 작업을 수행하는 더 빠른 방법을 찾고 싶습니다.

맥락: "FromTheseShadyIPs.txt"는 200,000개의 의심스러운 IP 주소 목록이고 "RemoveTheseGoodIPs.txt"는 3,000개의 양호한 IP로 구성된 화이트리스트 파일입니다. 결국 외부 방화벽이 참조할 수 있는 블랙리스트를 생성했지만 3,000개의 양호한 IP가 블랙리스트에 표시되는 것을 원하지 않습니다. 도움이 된다면 두 파일의 IP 순서는 중요하지 않으며 이미 각 파일에서 중복 제거되었습니다. 처리 서버는 괜찮은 사양의 Debian 9를 실행하고 있습니다.

답변1

해당 옵션을 추가해 보세요 -F. 정규식 처리를 수행하지 않고 입력을 문자열 리터럴로 해석합니다.

답변2

스크립트에는 실행 속도보다 더 중요한 문제가 있으며 다음 두 가지 방식으로 불일치가 발생합니다.

  1. 정규식 대 문자열: 문자열 비교를 사용해야 하는데 정규식 비교를 사용하고 있습니다. 작성된 대로 .RemoveTheseGoodIPs.txt의 IP 주소에 있는 s는 FromTheseShadyIPs.txt의 모든 문자와 일치합니다.
  2. 부분 대 전체: 전체 행 비교를 사용해야 하는데 부분 행 비교를 사용하고 있습니다. 작성된 대로 RemoveTheseGoodIPs.txt의 더 짧은 IP 주소는 FromTheseShadyIPs.txt의 해당 주소를 포함하는 모든 IP 주소와 일치합니다.

이를 감안할 때 현재 스크립트는 RemoveTheseGoodIPs.txt에 존재하지 않는 IP 주소를 FromTheseShadyIPs.txt에서 거의 확실하게 제거하여 방화벽을 효과적으로 파괴합니다.

예를 들어 RemoveTheseGoodIPs.txt를 포함 1.2.3.4하고 FromTheseShadyIPs.txt를 포함 하면 911.253.456.789필요한 전체 줄 문자열 일치 대신 부분 줄 정규식 일치를 수행하므로 grep이 두 번째 IP 주소를 제거합니다.

$ head RemoveTheseGoodIPs.txt FromTheseShadyIPs.txt
==> RemoveTheseGoodIPs.txt <==
1.2.3.4

==> FromTheseShadyIPs.txt <==
9.8.7.6
911.253.456.789
6.7.8.9

$ grep -v -f RemoveTheseGoodIPs.txt FromTheseShadyIPs.txt
9.8.7.6
6.7.8.9

당신은 사용해야합니다

$ grep -vFxf RemoveTheseGoodIPs.txt FromTheseShadyIPs.txt
9.8.7.6
911.253.456.789
6.7.8.9

스크립트를 작동시키세요. 이는 -F정규식 비교보다는 문자열을 위한 것이고, -x부분 비교보다는 전체 행을 위한 것입니다. 이는 현재 스크립트보다 빠를 수도 있지만 더 중요한 차이점은 강력하게 작동한다는 것입니다.

grep이 이러한 옵션을 지원하지 않고 지원되는 버전을 얻을 수 없는 경우 awk와 함께 다음을 사용할 수 있습니다.

$ awk 'NR==FNR{a[$0]; next} !($0 in a)' RemoveTheseGoodIPs.txt FromTheseShadyIPs.txt
9.8.7.6
911.253.456.789
6.7.8.9

~처럼댓글에 @Paul_Pedant가 언급되었습니다.그럼에도 불구하고, grep 및 awk 구현에 따라 awk를 사용하는 것이 grep보다 빠를 수 있습니다.

관련 정보