두 파일을 비교하고, 일치하는 콘텐츠를 무시하고, 파일 2의 일치하지 않는 콘텐츠를 특정 형식으로 파일 1에 추가합니다.

두 파일을 비교하고, 일치하는 콘텐츠를 무시하고, 파일 2의 일치하지 않는 콘텐츠를 특정 형식으로 파일 1에 추가합니다.

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하면 스크립트의 나머지 부분이 두 번째 파일에 대해서만 실행됩니다( NRAND가 다른 경우) FNR.
  • !($1$2 in a): 행의 첫 번째 필드와 두 번째 필드가 배열의 키로 사용되지 않는 경우 a(이는 첫 번째 필드와 두 번째 필드가 연결되어 있음을 의미하므로 첫 번째 필드가 연결되면 foo두 번째 필드도 연결됩니다). bar$1$2foobar
  • {print "2019",$0,"0"}: 2019현재 행의 합계를 인쇄합니다.file20

답변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

awkRoVo나 Tendon만큼 순수한 솔루션은 아니지만 join원하는 행을 "필터링"하는 데 사용할 수 있기 때문에 흥미로운 솔루션이라고 생각합니다.

관련 정보