一致する項目が複数ある場合は、特定の列値に基づいて2つのファイル間の共通行をgrepします。

一致する項目が複数ある場合は、特定の列値に基づいて2つのファイル間の共通行をgrepします。

ファイル1の列3とファイル2の列2を一致させたいのですが、その後に一致する行のすべての列を1行に印刷したいのですが、方法はわかりますが、問題はファイル2の列2に固有の値がないケースです。その後、出力はfile2です。最後に一致する行です。しかし、別々のファイルに複数の一致する行があり(衝突)、出力ファイルの一意の行だけを一致させたいと思います。
例:-
次の 2 つのファイルがあります。

file1

abc ram_1 ram1  
abc ram[0] ram0  
bcd raghu_reg_9 raghu9  
cde tanu/8 tanu8 

file2

1 ram1  
2 thakur56  
3 ram0  
4 ram1  
5 ram2  
6 raghu9  
7 raghu  

私は次のようにawkを使ってみました。

awk 'FNR==NR{a[$2]=$0;next} { if ($3 in a){print a[$3],$1,$2}}' file2 file1  

結果は次のとおりです。

4 ram1 abc ram_1  
3 ram0 abc ram[0]  
6 raghu9 bcd raghu_reg_9 

しかし、私は出力1が次のようになりたいと思います。

3 ram0 abc ram[0]  
6 raghu9 bcd raghu_reg_9  

出力2は次のとおりです。

1 ram1 abc ram_1  
4 ram1 abc ram_1  

ファイル 2 の列 2 に 2 つの ram1 エントリがあるため、ファイル 1 の列 3 の ram1 をファイル 2 の列 2 の ram1 と一致させる場合、これは 2 回一致し、2 番目の ram1 を出力として提供しますが、次のようになります.状況が発生した場合は、どの行を選択するかを手動で判断できるように、競合する行を別のファイルに移動する必要があります。

ベストアンサー1

join(1)以下を使用して、一致する各キーのファイルを1行にまとめることができます。

$ join -1 3 -2 2 -o 2.1,2.2,1.1,1.2 <(sort -k3,3 file1) <(sort -k2,2 file2)
6 raghu9 bcd raghu_reg_9
3 ram0 abc ram[0]
1 ram1 abc ram_1
4 ram1 abc ram_1

その機能は、ファイル1のフィールド3(-1 3)とファイル2のフィールド2()-2 2にある2つのファイルを連結し、ファイル2のフィールド1と2を出力し、ファイル1(-o 2.1,2.2,1.1,1.2)のフィールド1と2を出力することです。 。

結合では、各入力ファイルが結合フィールドでソートされる必要があるため、プロセス置換を<(sort -k3,3 file1)使用して同時入力パイプを実行し、それを結合コマンドに提供します。<(sort -k2,2 file2)bash(1)

uniq(1)この出力を使用すると、一意で重複した行を抽出できます。上記のコマンドを呼び出すには、joinit次のようにします。

$ joinit | uniq -u -f 1
6 raghu9 bcd raghu_reg_9
3 ram0 abc ram[0]

-u最初のフィールド()をスキップしてから唯一の行()を印刷します-f 1

$ joinit | uniq -D -f 1
1 ram1 abc ram_1
4 ram1 abc ram_1

-D最初のフィールド()をスキップしてから、すべての重複行()を印刷します-f 1

これを組み合わせて出力を合計output1するには、output22つの別々のフィルタを介してパイプラインにデータを供給できますtee(1)joinit

$ join -1 3 -2 2 -o 2.1,2.2,1.1,1.2 <(sort -k3,3 file1) <(sort -k2,2 file2) \
  | tee >(uniq -u -f 1 > output1) | uniq -D -f 1 > output2

繰り返しますが、これはbash(1)「プロセス置換」を利用して、同時出力パイプが各パイプに異なるコマンドを供給するようにしますuniq

おすすめ記事