2개의 순서가 지정된 문자열 목록이 있는 파일의 행 일치

2개의 순서가 지정된 문자열 목록이 있는 파일의 행 일치

일부 환경(목록 A)이 대상이고 다른 환경(목록 B)이 소스인 파일에서 액세스 목록 줄을 일치시키려고 합니다. 그 반대.

이것은 우분투 서버에 있습니다.

문제는 이러한 목록의 길이가 각각 약 15줄이므로 꽤 많은 조합과 매우 긴 grep 명령이 발생한다는 것입니다. 검색 중인 파일은 총 약 3000줄입니다.

파일의 줄을 파일의 줄과 일치시키면 이를 수행할 수 있다는 것을 알고 있지만 grep -f특정 검색 요구 사항을 충족하는 솔루션을 찾을 수 없습니다. 두 목록에서 검색 중이므로 순서가 중요합니다.

내가 하려는 작업의 예(각 IP 주소 줄에 관련 환경이 추가된 파일에서 검색하기 때문에 대괄호는 의도적인 것입니다):

목록 A 콘텐츠:

(One)
Two
Three

표 B의 내용:

(Four)
(Five)
(Six)

검색 중인 파일:

access-list acl-name line 1 extended permit tcp host 1.2.3.4 (One) host 5.6.7.8 Two eq ssh
access-list acl-name line 1 extended permit tcp host 1.2.3.4 (One) host 5.6.7.8 (Four) eq ssh
access-list acl-name line 1 extended permit tcp host 1.2.3.4 (Four) host 5.6.7.8 Three eq ssh
access-list acl-name line 1 extended permit tcp host 1.2.3.4 (Six) host 5.6.7.8 (One) eq ssh
access-list acl-name line 1 extended permit tcp host 1.2.3.4 (Five) host 5.6.7.8 (Five) eq ssh

원하는 출력(A를 대상으로 나열):

access-list acl-name line 1 extended permit tcp host 1.2.3.4 (Six) host 5.6.7.8 (One) eq ssh
access-list acl-name line 1 extended permit tcp host 1.2.3.4 (Four) host 5.6.7.8 Three eq ssh

원하는 출력(B를 대상으로 나열):

access-list acl-name line 1 extended permit tcp host 1.2.3.4 (One) host 5.6.7.8 (Four) eq ssh

나는 Ubuntu에서 사용할 수 있는 모든 명령이나 Python 스크립트에 열려 있습니다.

현재 내 grep 검색은 다음과 같습니다(목록 B가 대상이고 목록 A가 소스인 일치하는 행의 경우).

grep -iE '\(One\).*\(Four\)|Two.*\(Four\)|Three.*\(Four\)|\(One\).*\(Five\) and so on... '

도움을 주셔서 감사합니다. 현재 스크립트의 문자 수를 15000자에서 줄일 수 있기를 바랍니다. :)

답변1

내부 변수 에 대해 GNU Awk를 사용할 수 있다고 가정하면 FPAT다음 프로그램이 작동해야 합니다.

awk 'BEGIN{FPAT="host ([[:digit:]]+.){3}[[:digit:]]+ [^ ]+"}
     t=="src"{src[$0];next}
     t=="dst"{dest[$0];next}
     {split($1,a,/ /);lsrc=a[3]; split($2,a,/ /);ldst=a[3]}
     (lsrc in src && ldst in dest)' t="src" listA t="dst" listB t="" access

프로그램이 호출되어 세 개의 파일을 처리합니다. 각 처리 실행마다 변수는 처리된 파일을 식별할 수 있도록 서로 다른 값으로 설정 awk됩니다 .t

  • t로 설정된 경우 src프로그램은 이것이 "소스" 목록이라고 가정하고 행 내용을 연관 배열로 읽습니다 src(단, 실제로 항목에 값을 할당하지 않고 배열 인덱스만 채웁니다). 그런 다음 처리는 즉시 파일의 다음 줄로 이동합니다.선행 또는 후행 공백은 있을 수 없습니다. 그렇지 않으면 패턴 일치에 포함됩니다. 또한 이후 일치에서는 줄에 내부 공백 없이 하나의 연속 문자열만 포함되어 있다고 가정합니다.
  • t로 설정된 경우 dst프로그램은 이것이 "대상" 목록이라고 가정하고 유사하게 모든 행 내용을 배열에 등록합니다 dest.

다른 값이 있는 경우 t프로그램은 해당 값이 "기본" 액세스 목록에 있다고 가정하고 실제 일치를 수행합니다.

  • 여기에서는 FPAT이 섹션에서 설정한 내부 변수가 BEGIN작동합니다. 패턴과 일치하는 모든 부분을 "필드", hostIPv4 주소(기본 양식 확인만 수행), 각각 단일 공백으로 구분된 단일 연속 문자열로 처리합니다.
  • 첫 번째 필드에는 "소스" 부분이 포함되어 있습니다. 공간에서 배열로 분할되고 a세 번째 배열 항목("환경" 부분)은 지역 변수에 저장됩니다 lsrc.
  • 두 번째 필드도 유사하게 처리되며 "환경" 부분은 로컬 변수에 저장됩니다 ldst.
  • 규칙 블록 외부에는 행 인쇄 여부를 결정하는 부울 조건이 있습니다. lsrc배열의 인덱스 내에 포함되어 있으면 다음 행을 인쇄합니다.src 그리고ldst배열의 인덱스에 포함되어 있습니다 dest.

listA첫 번째 파일과 두 번째 파일로 사용된 결과 listB는 다음과 같습니다.

> awk ' ... ' t="src" listA t="dst" listB t="" access
access-list acl-name line 1 extended permit tcp host 1.2.3.4 (One) host 5.6.7.8 (Four) eq ssh

반대의 경우 listB첫 번째 파일과 listA두 번째 파일로 사용됩니다.

> awk ' ... ' t="src" listB t="dst" listA t="" access
access-list acl-name line 1 extended permit tcp host 1.2.3.4 (Four) host 5.6.7.8 Three eq ssh
access-list acl-name line 1 extended permit tcp host 1.2.3.4 (Six) host 5.6.7.8 (One) eq ssh

관련 정보