단락 패턴의 "패턴 파일"에서 여러 패턴 일치 [닫기]

단락 패턴의 "패턴 파일"에서 여러 패턴 일치 [닫기]

입력 파일이 있고 단락 내에서 다른 일치 항목을 검색해야 하며 일치 항목이 있으면 전체 단락이 포함된 출력 파일로 이동해야 합니다.

한 가지 중요한 점은 출력 순서가 입력 순서를 반영해야 한다는 것입니다. 그래서 단락을 검색해야 해요모두패턴 일치 파일의 패턴(한 줄에 하나의 패턴), 그리고하나패턴 일치 해당 단락에 대한 추가 일치를 중지하고 일치하는 단락을 출력 파일로 이동하고 다음 단락으로 처리를 건너뜁니다.

입력 파일:

DFJKHDKQW
YYYYYYYYYYYY
SDFLKJHSDKLFH

DSFLKHSDLKFH
DFIHERFW
ADFKJH
OIGHRFGH
XXXXXXXXXXXX
SDKFLJH

DFLKHSDFKLH
SDSDJKLFHSDK

OIHGSDFG
AAAAAAAA
LFKHFGJKDGH
KLJHLUG

DFSDKLF
YYYYYYYYYYYY

패턴 일치 파일:

AAAAAAAA
YYYYYYYYYYYY
XXXXXXXXXXXX

예상 출력:

DFJKHDKQW
YYYYYYYYYYYY
SDFLKJHSDKLFH

DSFLKHSDLKFH
DFIHERFW
ADFKJH
OIGHRFGH
XXXXXXXXXXXX
SDKFLJH

OIHGSDFG
AAAAAAAA
LFKHFGJKDGH
KLJHLUG

DFSDKLF
YYYYYYYYYYYY

awk나는 지금 상상을 초월하는 일련의 문제에 직면해 있습니다 .

  1. 입력 파일을 사용하여 패턴 일치
  2. 처음 나타날 때 단락을 회전하고 "다음 단락으로 중지/점프"
  3. 일치하는 단락을 출력 파일에 복사합니다.
  4. 입력에서 일치하는 단락을 삭제합니다( diff나중에 두 파일 사이를 통해 이 작업을 수행할 수 있으므로 선택 사항).

답변1

전체 줄 문자열 일치를 수행한다고 가정하면 다음이 필요합니다.

$ cat tst.awk
BEGIN {
    ORS = "\n\n"
    FS = "\n"
}
NR==FNR {
    tgts[$0]
    next
}
{
    out = "unmatched"
    for (i=1; i<=NF; i++) {
        if ($i in tgts) {
            out = "matched"
            break
        }
    }
    print > out
}

$ awk -f tst.awk targets RS= file

$ ls *matched
matched  unmatched

$ head -100 *matched
==> matched <==
DFJKHDKQW
YYYYYYYYYYYY
SDFLKJHSDKLFH

DSFLKHSDLKFH
DFIHERFW
ADFKJH
OIGHRFGH
XXXXXXXXXXXX
SDKFLJH

OIHGSDFG
AAAAAAAA
LFKHFGJKDGH
KLJHLUG

DFSDKLF
YYYYYYYYYYYY


==> unmatched <==
DFLKHSDFKLH
SDSDJKLFHSDK

문자열 일치 대신 정규식을 수행해야 하거나 정확히 일치하는 대신 부분을 수행해야 하는 경우 다른 솔루션이 필요합니다(그리고 요구 사항을 더 잘 설명하기 위해 질문을 업데이트하십시오).

답변2

패턴 일치match각각을 하나의 별도 패턴으로 입력하세요.infile입력하고 시도해 보세요:

awk -F'\n' '!input && !matches[$0]{ next; };
    { for(i=1; i<=NF; i++) {
          if($i in matches) { print sep $0; sep=ORS; break; };
      };
    }' match input=1 RS= infile

또는 패턴 일치match패턴 블록을 입력하세요.infile입력(동일한 블록을 추가합니다.match입력infile확인하기 위해) 다음을 시도해 보세요.

awk -v RS= '!input && !matches[$0]{ next; }; ($0 in matches)' match input=1 infile

답변3

단락 모드를 이미 알고 있으므로 다음이 작동합니다. 먼저 "스키마" 파일을 구문 분석한 다음 실제 입력을 구문 분석합니다. 출력은 평소와 같이 콘솔에 인쇄되지만 물론 파일로 리디렉션될 수도 있습니다.

awk -v ORS="\n\n" 'NR==FNR{pat[++npat]=$0;next}
                   {for (i=1;i<=npat;i++) {if (index($0,pat[i])) {print;next}}}' patterns.txt RS="" input.txt
  • 이는 먼저 출력 레코드 구분 기호를 두 개의 줄 바꿈으로 설정하여 인쇄된 단락이 입력에서와 같이 빈 줄로 구분되도록 합니다.

  • 첫 번째 파일을 처리할 때( FNR파일별 라인 카운터가 NR글로벌 라인 카운터와 동일함) 모든 패턴을 배열 변수에 저장하기만 하면 됩니다 pat.

  • 두 번째 파일의 경우 레코드 구분 기호는 공백으로 설정되어 있으며 이는 awk"단락 모드"에서 실행 중임을 나타냅니다. 그런 다음 모든 패턴을 반복하고 index()함수를 통해 입력 레코드에서 해당 패턴이 발견되는지 명시적으로 확인합니다.

노트

  • 이 솔루션은 "부분 문자열 일치"를 수행합니다. 즉, 줄 중 하나에서 어떤 종류의 "패턴"이 발견되면 해당 단락이 일치하는 것으로 간주됩니다.

  • index()기능은 다음을 보장하기 때문에 사용됩니다.단어"검색 패턴"에 정규식에 고유한 문자가 포함되어 있는 경우에도 문자열이 일치합니다. 실제로 정규식 일치를 사용하려면 if ($0 ~ pat[i])이를 대신 사용하십시오.

관련 정보