일치하는 ID와 일치하지 않는 ID의 첫 번째 열

일치하는 ID와 일치하지 않는 ID의 첫 번째 열

input.txt,Linux 시스템에 서로 다른 열( 구분 기호) 을 포함하는 두 개의 파일이 있습니다 . 각 파일의 첫 번째 열에 보고된 ID를 사용하여 이러한 파일을 결합하는 스크립트가 있습니다. 이 스크립트는 출력에서 ​​첫 번째 파일의 모든 ID를 유지하고 두 번째 파일의 일치하는 ID만 유지합니다. 첫 번째 파일의 ID와 일치하지 않는 두 번째 파일의 ID를 유지하는 옵션을 추가하여 이 스크립트를 구현해야 합니다.

예:

2931,C,-9.750,-2.550,57.910,-0.3,C
2932,C,-5.470,-0.200,51.550,0.9,C
2940,C,-10.860,-3.400,54.000,0.7,C
2941,S,-11.820,-13.550,55.070,2.1,S
2944,H,-3.770,-4.180,60.300,0.7,H

2.txt를 입력하세요

4304,N,-9.700,-7.680,58.330,-2.3,N
2940,S,-10.440,-3.450,54.270,2.2,S
2900,C,-13.655,-13.730,59.405,-1.5,C
2931,C,-9.910,-2.420,57.610,0.2,C

주문하다:

join -t, -a1 -o auto <(sort input1.txt) <(sort input2.txt) > output.txt.txt

출력.txt

2931,C,-9.750,-2.550,57.910,-0.3,C,2931,C,-9.910,-2.420,57.610,0.2,C
2932,C,-5.470,-0.200,51.550,0.9,C,,,,,,,
2940,C,-10.860,-3.400,54.000,0.7,C,2940,S,-10.440,-3.450,54.270,2.2,S
2941,S,-11.820,-13.550,55.070,2.1,S,,,,,,,
2944,H,-3.770,-4.180,60.300,0.7,H,,,,,,,

두 개의 출력 파일을 얻기 위해 명령을 수정하고 싶습니다. 첫 번째 항목은 지금 받는 것과 유사해야 하지만 ID도 일치하지 않아야 합니다.

final.txt 출력

2931,C,-9.750,-2.550,57.910,-0.3,C,2931,C,-9.910,-2.420,57.610,0.2,C
2932,C,-5.470,-0.200,51.550,0.9,C,,,,,,,
2940,C,-10.860,-3.400,54.000,0.7,C,2940,S,-10.440,-3.450,54.270,2.2,S
2941,S,-11.820,-13.550,55.070,2.1,S,,,,,,,
2944,H,-3.770,-4.180,60.300,0.7,H,,,,,,,
,,,,,,,2900,C,-13.655,-13.730,59.405,-1.5,C
,,,,,,,4304,N,-9.700,-7.680,58.330,-2.3,N

다른 출력 파일에는 일치하지 않는 다음 줄만 포함되어야 합니다 input2.txt.

출력2.txt

2900,C,-13.655,-13.730,59.405,-1.5,C
4304,N,-9.700,-7.680,58.330,-2.3,N

또한 input2.txt에서 ID가 4000 이상인 행의 마지막 열 요소만 문자열 "P"로 바꾸려면 어떻게 해야 합니까?

즉, 첫 번째 행(ID = 4304)의 마지막 "C"를 "P"로 바꾸고 싶습니다.

출력.txt

4304,N,-9.700,-7.680,58.330,-2.3,P
2940,S,-10.440,-3.450,54.270,2.2,S
2900,C,-13.655,-13.730,59.405,-1.5,C
2931,C,-9.910,-2.420,57.610,0.2,C

답변1

직업 1:

ID파일이 고유하다고 가정하면 awk 다음과 같이 사용할 수 있습니다.

awk -F, -v OFS=, '
    NR == FNR {
        m[$1] = $0 
        while (i++ <= NF) empty = OFS empty
        next
    }
    !m[$1]{$0 = $0 OFS empty}
    m[$1]{$0 = $0 OFS m[$1];delete m[$1]}
    1
    END{
        for ( i in m )
            if(m[i]) print empty, m[i]
    }
' file2 file1

파일을 정렬할 필요는 없습니다. 공개 필드를 발견할 때마다 배열에서 제거하십시오. 마지막으로 배열은 방금 나타난 콘텐츠만 보유합니다.file2


직업 2:

awk -F, 'NR == FNR {m[$1];next} !($1 in m)' file1 file2

출력 리디렉션을 사용하여 처음 두 내용을 쉘 스크립트에 넣습니다.

#!/bin/bash

# first awk cmd
... > output1.txt

# Second awk cmd
... > output2.txt

답변2

join모든 필드를 포함하도록 지시하면 원하는 첫 번째 출력 파일을 얻을 수 있습니다. 이 파일은 두 파일의 모든 ID를 포함하는 파일입니다.

$ join -t, -a1 -a2 -o 1.1,1.2,1.2,1.4,1.5,1.6,1.7,2.1,2.2,2.2,2.4,2.5,2.6,2.7 \
   <(sort input1.txt) <(sort input2.txt) 
,,,,,,,2900,C,C,-13.730,59.405,-1.5,C
2931,C,C,-2.550,57.910,-0.3,C,2931,C,C,-2.420,57.610,0.2,C
2932,C,C,-0.200,51.550,0.9,C,,,,,,,
2940,C,C,-3.400,54.000,0.7,C,2940,S,S,-3.450,54.270,2.2,S
2941,S,S,-13.550,55.070,2.1,S,,,,,,,
2944,H,H,-4.180,60.300,0.7,H,,,,,,,
,,,,,,,4304,N,N,-7.680,58.330,-2.3,N

순서는 파일에서 발견되는 순서이기 때문에 표시된 것과 다릅니다( ,,,,,,,2900...가 먼저 나타남 sort input2.txt).

,그런 다음 첫 번째 출력 파일을 구문 분석하고 하나 이상의 문자로 시작하는 줄을 찾아 두 번째 출력 파일을 얻을 수 있습니다.

$ join -t, -a1 -a2 -o 1.1,1.2,1.2,1.4,1.5,1.6,1.7,2.1,2.2,2.2,2.4,2.5,2.6,2.7 \
   <(sort input1.txt) <(sort input2.txt) | grep -oP '^,+\K.*'
2900,C,C,-13.730,59.405,-1.5,C
4304,N,N,-7.680,58.330,-2.3,N

이 옵션은 행에서 일치하는 부분만 인쇄하도록 -o지시 하고 Perl 호환 정규식을 활성화합니다. 그런 다음 PCRE는 "여기에 일치하는 항목은 모두 무시"라는 의미를 제공하므로 확장된 부분만 인쇄할 수 있습니다 .grep-P\K,

tee첫 번째 출력을 파일에 쓰고 이를 표준 출력에 쓰는 두 개의 파일을 만드는 단일 명령으로 결합할 수 있으며 , 그런 다음 grep위와 같이 실행할 수 있습니다.

join -t, -a1 -a2 -o 1.1,1.2,1.2,1.4,1.5,1.6,1.7,2.1,2.2,2.2,2.4,2.5,2.6,2.7 \
    <(sort input1.txt) <(sort input2.txt) | 
        tee output1.txt | grep -oP '^,+\K.*' > output2.txt

최종 출력은 다음과 같습니다.

$ cat output1.txt 
,,,,,,,2900,C,C,-13.730,59.405,-1.5,C
2931,C,C,-2.550,57.910,-0.3,C,2931,C,C,-2.420,57.610,0.2,C
2932,C,C,-0.200,51.550,0.9,C,,,,,,,
2940,C,C,-3.400,54.000,0.7,C,2940,S,S,-3.450,54.270,2.2,S
2941,S,S,-13.550,55.070,2.1,S,,,,,,,
2944,H,H,-4.180,60.300,0.7,H,,,,,,,
,,,,,,,4304,N,N,-7.680,58.330,-2.3,N


$ cat output2.txt 
2900,C,C,-13.730,59.405,-1.5,C
4304,N,N,-7.680,58.330,-2.3,N

관련 정보