一致するIDと一致しないIDの最初の列

一致するIDと一致しないIDの最初の列

input.txt,Linuxシステムには、異なる列(区切り文字)を含む2つのファイルがあります。各ファイルの最初の列に報告されたIDを使用してこれらのファイルを結合するスクリプトがあります。このスクリプトは、出力内の最初のファイルのすべてのIDを保持し、2番目のファイルの一致するIDのみを保持します。最初のファイルのIDと一致しない2番目のファイルの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,,,,,,,

2つの出力ファイルを取得するためにコマンドを変更したいと思います。最初の項目は今受け取るものと似ていなければなりませんが、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で4000以上のIDを持つ行の最後の列要素のみを文字列「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

出力リダイレクトを使用して、最初の2つの内容をシェルスクリプトに入れます。

#!/bin/bash

# first awk cmd
... > output1.txt

# Second awk cmd
... > output2.txt

おすすめ記事