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
하므로 명령에 제공된 첫 번째 파일 인수를 처리하도록 설계되었습니다 . 따라서 첫 번째 파일의 각 값에 대해 해당 값은 라는 배열로 해시되고 ,FNR
NR
$1
hash
다음파일 처리가 발생하면 이 섹션에서는 $0 in hash
해당 행을 해시 인덱스 위치에 매핑합니다. 그러한 매핑된 라인의 경우 해당 라인을 인쇄하고, 매핑되지 않은 라인의 경우 를 인쇄합니다.file1
file2
0
이는 개별 필드 또는 상기 특수 변수에 대한 수정 사항을 기반으로 전체 행을 기본적으로 다시 작성/인쇄하는 {..}1
간단한 표현입니다 .{..; print}
답변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