2つのファイルがあり、file1 2nsおよび3 ed列をfile2の最初と2番目の列と比較する必要があります。一致した場合は保持し、そうでない場合は2019を最初の列として追加し、最後の列データとしてゼロを追加して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
)を読み取るときは、2番目と3番目のフィールドを連想配列のキーとして使用しますa
。これは私たちがすでに見たことを追跡することです。その後、この行を印刷して次の行に進みます。これnext
により、スクリプトの残りの部分が2番目のファイルに対してのみ実行されます(NR
ANDが異なる場合)FNR
。!($1$2 in a)
:行の最初のフィールドとa
2番目のフィールドが配列のキーとして使用されていない場合(これは、最初のフィールドと2番目のフィールドがリンクされていることを意味するため、最初のフィールドがリンクされている場合はfoo
2番目のフィールドもリンクされます)。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
目的の行を「フィルタリング」するために使用できるので、興味深いソリューションだと思います。