두 개의 큰 파일 사이의 Grep 또는 awk. 여기서 file1은 패턴 파일이고 file2는 데이터를 포함합니다.

두 개의 큰 파일 사이의 Grep 또는 awk. 여기서 file1은 패턴 파일이고 file2는 데이터를 포함합니다.

File1고정 길이 숫자가 있으며 한 줄에 숫자가 하나씩 있습니다.

1234
5678
1345

File2"key=value" 형식의 데이터 필드를 포함합니다.

abc:def=1999,xyz=1234;
abc:def=5678,xyz=1234;
abc:def=1234,xyz=5678;

필드가 의 숫자와 일치하는 행을 가져와야 File2하지만 패턴 일치 중에 필드가 무시 됩니다 def. 따라서 내 결과는 다음과 같아야 합니다.File1xyz

abc:def=5678,xyz=1234;
abc:def=1234,xyz=5678;

답변1

나는 항상 대부분의 awk명령을 잊어버리고 그것은 내 오래된 두뇌에 너무 부담스럽기 때문에 대안을 제공합니다 sed.

sed '/^[0-9]*$/H;G;/def=\([0-9]*\),.*\n\1/P;d' file1 file2

아이디어는 예약된 공간에서 숫자를 수집 file1하고 역참조를 사용하여 다음 숫자가 포함된 file2의 해당 행을 식별하는 것입니다.def=

  • 이 패턴은 ^[0-9]*$숫자만 포함된 행과 일치합니다. 이는 행이며 이전 공간 file1에 추가합니다.H
  • G예약된 공간을 패턴 공간에 추가하여 패턴 공간에 file2행과 모든 숫자를 갖게 됩니다.file1
  • 이 패턴은 개행 문자 뒤에 /def=\([0-9]*\),.*\n\1다음 숫자(역참조)가 반복되는 모든 행을 처리합니다(따라서 예약된 공간 집합의 일부임). 추가 내용 없이 줄 인쇄def=\1P
  • d추가 출력을 억제합니다. -n대신 옵션을 사용할 수 있습니다

업데이트: 시각적 설명

Ed가 지적했듯이, 내 설명은 분명히 모든 사람에게 도움이 되지는 않을 것입니다. 당신이 "시각적 사고"에 더 가깝다면 이것이 어떻게 작동하는지 설명하려고 노력할 것입니다. 이것은 sed프로그래밍 도구가 아니라 다음 기능을 갖춘 자동 텍스트 편집기에 가깝습니다.예비 공간줄을 읽는 동안 "클립보드"로 사용패턴 공간, 작업이 완료된 곳입니다.

이제 제안된 대로 H및 명령 G뒤에 두 개의 공백을 표시합니다 .

패턴 공간 예비 공간 논평
1234 1234 H(빈) 예약된 공간에 추가 하고 줄 바꿈 포함
1234␤␤1234 1234 G패턴 공간에 다시 추가하고 또 다른 개행을 추가합니다.
5678 1234␤␤5678 다음 줄을 읽을 때 예약된 공간이 유지되므로 다음 줄 H에는 다음 번호가 추가됩니다.
56781234␤␤␤5678 1234␤␤5678 패턴 공간에 다시 추가되지만 여전히 def=패턴과 일치하지 않습니다.
file1가독성을 위해 세 번째 줄을 건너뛰세요.
abc:def=1999,xyz=1234; 1234␤␤5678 패턴과 일치하지 않으므로 ^[0-9]*$실행 H되지 않습니다.
abc:def=1999,xyz=1234;1234␤␤␤5678 1234␤␤5678 하지만 G처형됐다

P이제 명령의 주소 패턴을 적용하는 방법을 살펴보십시오( \n개행 문자의 자리 표시자로 사용됨).

abc:def=1999,xyz=1234;\n\n1234\n5678
    def=####,         .*                 #### stands for `[0-9]*`, but the back reference
                                         as `\1` is not found: no match

abc:def=5678,xyz=1234;\n\n1234\n5678
    def=####,         .*      \n####     here, the match is repeated as `\1`,so we know
                                         the `def` number has been listed in `file1` 

답변2

숫자를 해시( nums이 경우)로 수집하고 이를 사용하여 나중에 쉽게 찾을 수 있습니다.

awk -F '[=,;]' 'FNR==NR { nums[$1]; next } $2 in nums' file1 file2

산출:

abc:def=5678,xyz=1234;
abc:def=1234,xyz=5678;

필드 순서가 일정하지 않은 경우 다음 접근 방식을 사용할 수 있습니다.

awk -F'[=,;:]' '
  FNR==NR { nums[$1]; next }
  $2 == "def" && ($3 in nums) || $4 == "def" && ($5 in nums)
' file1 file2

답변3

grep -f <(sed 's/^/abc:def=/' file1.txt) file2.txt

또는 쉘이 이를 지원하지 않는 경우 새 파일을 생성할 수 있습니다 <().

sed 's/^/abc:def=/' file1.txt > patterns.txt
grep -f patterns.txt file2.txt

또는 fifo 파일을 만들 수 있습니다.

mkfifo fifo
sed 's/^/abc:def=/' file1.txt >fifo &
grep -f fifo file2.txt

관련 정보