file2에서 정확한 행 블록 (file1의 내용)을 grep


9

나는 두 개의 파일을 가지고 file1file2.

샘플 내용 file1은 다음과 같습니다.

A B
C D
E F
G H

내용 file2은 다음과 같습니다.

A B
few other lines
E F
few more other lines
A B
C D
E F
G H
few more other lines
G H

전체 file1콘텐츠 블록 file2만 검색하고 싶습니다 . 이것은 출력에 다음 줄만 포함되어야 함을 의미합니다.

A B
C D
E F
G H

참고 :-함께 오는 줄만 출력의 일부가되어야합니다.


질문이 없습니다. 정확한 내용 만 인쇄하고 싶을 file1때는을 사용하십시오 cat file1.
와일드 카드

@Wildcard 그는 file2에 file1과 정확히 동일한 내용이 포함되어 있는지 확인하려고합니다. 책에서 특정 챕터를 찾는 것처럼 생각하십시오
Sergiy Kolodyazhnyy

"집합 멤버"가 여러 줄로 구성되어 있기 때문에 이것을 다시 열겠다고 투표하고 있습니다.
Kusalananda

1
이것은 세트에 관한 것이 아닙니다 . 이것을 중복으로 표시하려면 최소한 여러 줄 정규식에 대한 다른 질문을 찾으십시오.
Michael Vehrs

답변:


11

grep여러 줄 패턴에 관해서는 매우 어리석지 만 \n패턴과 텍스트의 줄 바꿈 문자 를 모두 번역 하여 NUL 문자로 검색하면 \0이를 수정합니다. \0출력을 다시 번역 하는 \n것도 분명히 필요합니다.

file1검색하려는 패턴 이 포함되어 있다고 가정하면 명령은 다음과 같습니다 file2.

grep -aof <(tr '\n' '\0' < file1) <(tr '\n' '\0' < file2) | tr '\0' '\n'

주어진 파일에 대한 예제 출력 :

A B
C D
E F
G H

설명:

  • <(tr '\n' '\0' < file1)FIFO / 명명 된 파이프 / 임시 파일과 유사한 객체를 생성 file1하지만 모든 개행 문자는 NUL 문자로 변환됩니다.
  • <(tr '\n' '\0' < file2)동일하지만을 수행 file2합니다.
  • grep -f PATTERN_FILE INPUT_FILE발 패턴 (들)에 대한 검색 PATTERN_FILE에서 INPUT_FILE.
  • -a플래그는 grep이진 파일에서 일치를 활성화합니다. 그렇지 않으면와 같은 인쇄 할 수없는 문자가 포함 된 파일을 건너 뛰기 때문에 필요합니다 \0.
  • of -o플래그는 grep발견 된 전체 행이 아니라 일치하는 순서 만 인쇄합니다.
  • | tr '\0' '\n' 왼쪽의 명령 출력에서 ​​모든 NUL 문자를 개행 문자로 다시 변환합니다.

6

다음은 어색하지만 GNU와 함께 작동합니다 awk.

awk -v RS="$(<file1)" '{print RT}' file2

3

순수한 배쉬에서 재미를 위해

mapfile -t <file1
while read line ; do
    [ "$line" = "${MAPFILE[i++]}" ] || { ["$line" = "$MAPFILE" ] && i=1 || i=0; }
    [ $i -eq ${#MAPFILE[*]} ] && { printf "%s\n" "${MAPFILE[@]}"; i=0; }
done <file2

3

좀 더 우아하고 grep+ perl:

$ grep -Pzo "$(perl -pe 's/\n/\\n/g' file1.txt )"  file2.txt                    
A B
C D
E F
G H

그러나 한 가지 큰 문제가 있습니다. 에 후행 줄 바꿈이 있으면 file1패턴이 올바르지 않습니다 A B\nC D\nE F\nG H\n\n. 즉, .

(펄 부분을 제공하는 @terdon에게 특별한 감사를드립니다)

costas 언급 한 바와 같이, perl -0pe 's/\n(\n+$)?/\\n/g' 다른 perl명령 대신에 줄 바꿈 줄을 피할 수 있습니다 .file1.txt


1
후행 줄 바꿈이 있고 OP가 아닌 경우 찾아야 perl -0pe 's/\n(\n+$)?/\\n/g'합니다. 없이 정규식 modificator 추가합니다. -0g
Costas

1

출력이 무엇을 원하는지 잘 모르겠지만 독점적으로 줄 지향적이지 않은 언어 (특히 두 파일을 모두 메모리로 읽을 수있는 경우)로 쉽게 할 수 있습니다. 다음은 일치하는 항목 수를 알려주는 Python 스크립트입니다.

import sys
find = open(sys.argv[1]).read()
hay = open(sys.argv[2]).read()
print("The text occurs", hay.count(find), "times")

file1일치하는 횟수만큼 인쇄하고 싶 습니까? 마지막 줄을 다음과 같이 바꾸십시오.

print(find * hay.count(find))

실제로 원하는 경우 모든 것을 명령 줄 호출 또는 별칭으로 묶을 수 있습니다.

python -c 'import sys; print("The text occurs", open(sys.argv[2]).read().count(open(sys.argv[1]).read()), "times")' file1 file2

1
grep -lir 'A B \n D C \n whatever' ./folder_to_search

결과는 정확히 일치하는 모든 파일이됩니다


0

다음은 파이썬을 사용하는 또 다른 접근법입니다 ( python3 3.5.2에서 불만없이 테스트했습니다 pylint3 1.5.6).

""" Locate entire file contents contiguous in other file """

import sys
import re
from mmap import mmap, PROT_READ

def memmap(name):
    """ Return memoryview of readonly mmap """
    with open(name, 'rb') as file:
        return memoryview(mmap(file.fileno(), 0, access=PROT_READ))

def finder(needle, haystack):
    """ Return iterator """
    return re.compile(re.escape(needle)).finditer(haystack)

print(tuple(finder(*(memmap(name) for name in sys.argv[1:3]))))

via를 통한 명령 행 인수 처리는 매우 sys.argv간단합니다. 전달 finder하는 두 memoryview객체 에 대한 반환 값을 로 전달하는 것 외에도 많은 다른 작업을 수행 할 수 tuple있습니다. SRE_Match이터레이터가 반환 한 각 항목은 finder다양한 방법을 가지며, 샘플링은 print출력에 요약됩니다 ( span예 : 각 일치의 바이트 범위를 나타냄).

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.