일치하는 문자를 사용하여 두 파일 병합

일치하는 문자를 사용하여 두 파일 병합
File1:
X
X
P
X
N
X
Q
File2:
P 1
N 5
Q 0

Desired output:
X 0
X 0 
P 1
X 0
N 5
X 0
Q 0

나는 bash에서 merge 명령을 사용하기 위해 여러 가지 방법을 시도했습니다. 나는 그것을 작동시킬 수 없습니다.

답변1

Awk아주 쉽게 할 수 있어요!

awk 'FNR==NR{ hash[$1]=$2; next}{ if ($0 in hash) $2 = hash[$1]; else  $2 = "0" }1' file2 file1

Awk입력 라인을 처리하여 작동합니다.하나한 번. 파일 처리 전후에 실행할 작업을 Awk제공 BEGIN{}하고 포함하는 특수 절도 있습니다 . END{}파일의 각 줄은 FS특수 변수(기본적으로 하나 이상의 공백) 값을 기준으로 분할되며 이러한 개별 필드는 $1, ..에서 $2액세스할 수 있습니다 .$NF

따라서 이 섹션은 결합된 파일과 현재 파일 의 줄 번호를 추적 FNR==NR하므로 명령에 제공된 첫 번째 파일 인수를 처리하도록 설계되었습니다 . 따라서 첫 번째 파일의 각 값에 대해 해당 값은 라는 배열로 해시되고 ,FNRNR$1hash다음파일 처리가 발생하면 이 섹션에서는 $0 in hash해당 행을 해시 인덱스 위치에 매핑합니다. 그러한 매핑된 라인의 경우 해당 라인을 인쇄하고, 매핑되지 않은 라인의 경우 를 인쇄합니다.file1file20

이는 개별 필드 또는 상기 특수 변수에 대한 수정 사항을 기반으로 전체 행을 기본적으로 다시 작성/인쇄하는 {..}1간단한 표현입니다 .{..; print}

더보기awk의 내장 변수 제어

답변2

를 사용하여 이 작업을 수행할 수 있지만 sed정규식 Gnu을 덜 복잡하게 만드는 편집기 버전이 있습니다.

기본 아이디어는 먼저 File2를 읽고 줄 바꿈으로 구분된 예약된 공간에 저장하는 것입니다.

그런 다음 File1을 읽고 File2의 줄을 방금 읽은 File1 줄에 추가합니다. 예약된 공간에서 File1 줄의 존재를 감지할 수 있으면 다른 콘텐츠의 패턴 공간을 잘라서 File2 줄을 있는 그대로 인쇄할 수 있습니다.

그렇지 않으면 File1 줄을 인쇄하고 0을 추가합니다.

$ sed -Ee '
    / /{H;d;}
    G
    s/^(\S+)\n.*\n(\1 \S+)(\n.*)?$/\2/;t
    s/\n.*/ 0/
' File2 File1

관련 정보