2개의 파일이 있고 file1 2ns 및 3 ed 열을 file2의 첫 번째 및 두 번째 열과 비교해야 합니다. 일치하면 유지하고, 그렇지 않으면 2019를 첫 번째 열로 추가하고 0을 마지막 열 데이터로 추가하여 file1을 추가해야 합니다. 가능합니까?
파일 1
2019 ABCD 1 10
2019 DEF 2 11
2019 GHI 1 20
2019 jkl 2 25
파일 2
ABCD 1
jkl 1
mnop 2
qrst 1
예상되는 결과
2019 ABCD 1 10
2019 DEF 2 11
2019 GHI 1 20
2019 jkl 2 25
2019 jkl 1 0
2019 mnop 2 0
2019 qrst 1 0
답변1
이 시도:
awk '
FNR==NR {seen[$2,$3]=1; print $0 }
FNR!=NR && !seen[$1,$2] { print 2019,$0,0 }
' file1 file2
설명하다:
FNR==NR { ... }
첫 번째 파일에서만 괄호 안의 명령을 실행합니다.seen[$2,$3]=1
,seen
$2,$3 키가 있는 배열을 1로 설정합니다.print $0
전체 줄을 인쇄합니다.FNR!=NR && !seen[$1,$2] { ... }
seen
괄호 안의 명령은 첫 번째 파일이 아니고 $1, $2 필드가 배열의 키가 아닌 경우에만 실행 됩니다.print 2019,$0,0
새 열 2019와 0으로 둘러싸인 행을 인쇄합니다.
정렬된 출력이 추가되었습니다 | column -t
.
산출:
$ awk 'FNR==NR{seen[$2,$3]++; print $0} FNR!=NR && !seen[$1,$2]{print 2019,$0,0}' file1 file2 | column -t
2019 ABCD 1 10
2019 DEF 2 11
2019 GHI 1 20
2019 jkl 2 25
2019 jkl 1 0
2019 mnop 2 0
2019 qrst 1 0
답변2
이것은 작동합니다:
$ awk 'NR==FNR{a[$2$3]++; print; next}!($1$2 in a){print "2019",$0,"0"}' file1 file2
2019 ABCD 1 10
2019 DEF 2 11
2019 GHI 1 20
2019 jkl 2 25
2019 jkl 1 0
2019 mnop 2 0
2019 qrst 1 0
설명하다
NR==FNR
: NR은 현재 줄 번호, FNR은 현재 파일의 줄 번호입니다. 첫 번째 파일을 읽는 경우에만 둘 다 동일합니다.{a[$2$3]++; print; next}
: 첫 번째 파일(file1
)을 읽을 때 두 번째 및 세 번째 필드를 연관 배열의 키로 사용합니다a
. 이는 우리가 이미 본 내용을 추적하기 위한 것입니다. 그런 다음 이 줄을 인쇄하고 다음 줄을 계속 진행하세요. 이렇게next
하면 스크립트의 나머지 부분이 두 번째 파일에 대해서만 실행됩니다(NR
AND가 다른 경우)FNR
.!($1$2 in a)
: 행의 첫 번째 필드와 두 번째 필드가 배열의 키로 사용되지 않는 경우a
(이는 첫 번째 필드와 두 번째 필드가 연결되어 있음을 의미하므로 첫 번째 필드가 연결되면foo
두 번째 필드도 연결됩니다).bar
$1$2
foobar
{print "2019",$0,"0"}
:2019
현재 행의 합계를 인쇄합니다.file2
0
답변3
다음은 매우 다른 접근 방식입니다.
mkns() {
# make keys from parameters $2 and $3 for joining, then sort the keys
sort -k 1b,1 <(awk "{print \$$2\$$3, \$0}" $1)
}
그런 다음 실행
join -j 1 -v 2 <(mkns file1 2 3) <(mkns file2 1 2) | awk '{print 2019, $2, $3, 0}' | cat file1 - | column -t
awk
RoVo나 Tendon만큼 순수한 솔루션은 아니지만 join
원하는 행을 "필터링"하는 데 사용할 수 있기 때문에 흥미로운 솔루션이라고 생각합니다.