入出力ファイルのデータマッチング

入出力ファイルのデータマッチング

私はUnixを初めて使用しています(1週間しか経っていません)、2つのファイルに問題があります

2|1019|0|12 
2|1019|3|0 
2|1021|0|2 
2|1021|2|0 
2|1022|4|5
2|1030|0|1 
2|1030|5|0 
2|1031|4|4

そして

2|1019|0|12 
2|1019|3|10 
2|1021|0|22 
2|1021|2|0 
2|1022|4|15

1 つは出力ファイル、もう 1 つは入力ファイルです。

2列の値が一致した場合は、2行の3列と4列の値を加算し、そうでなければ入力と出力の唯一の行の3列と4列の値を加算し、次に合計(3番目と4番目)を比較して差がある場合2 番目の列の値が合計と一致しないというメッセージを表示します。

合計は

1019 15
1021 4
1022 9
1030 6
1031 8

入力中

合計は

1019 25
1021 24
1022 19

出力から

Expected output 
Unequal total for 1019,1021,1022

注:入力と出力の値はパイプ(|)で区切られています。

このスクリプトを実行

awk -F '|' '{Arr[$2]=Arr[$2]+$3+$4}END{ for(i in Arr)print "amount for planId " i " is :"Arr[i]}'

最初のファイルからこの出力を取得します。

amount for planId  is :0
amount for planId 1019 is :12
amount for planId 1021 is :4
amount for planId 1022 is :9
amount for planId 1030 is :6
amount for planId 1031 is :8

最初の行がなぜ表示されるのかわかりません。

amount for planId  is :0

答え1

最初の2つのawkコマンドは、値を追加し、出力をf1.outとf2.outにリダイレクトするために使用されます。

最後は、f1.outとf2.outの値を比較することです。

$ awk '{Arr[$2]=Arr[$2]+$3+$4}END{for(i in Arr)print i,Arr[i]}' file1 > f1.out
$ awk '{Arr[$2]=Arr[$2]+$3+$4}END{for(i in Arr)print i,Arr[i]}' file2 > f2.out
$ awk 'NR==FNR{Arr[$1]=$2;next}{if(Arr[$1]!=$2){out=$1","out;}}END{print out}' f1.out f2.out

答え2

別のawk方法:

$ awk 'NR==FNR{a[$2]+=$3+$4; next} {b[$2]+=$3+$4;}
       END{
           for(i in a){
             if(i in b && a[i]!=b[1]){
                print "Unequal total for",i
             }
           }
       }' input output 
Unequal total for 1019
Unequal total for 1021
Unequal total for 1022

または質問に示されている正確な出力が本当に必要な場合:

$ awk 'NR==FNR{a[$2]+=$3+$4; next} {b[$2]+=$3+$4;}
       END{
            for(i in a){
                if(i in b && a[i]!=b[1]){
                    c[i]
                }
            } 
            printf "Unequal total for "; 
            for(i in c){printf "%s, ", i}
        }' input output | perl -pe 's/,\s*$/\n/'
Unequal total for 1019, 1021, 1022

FNR現在のファイルの行番号であり、NRすべての入力の合計行番号です。 2 つは、最初のファイルを読み取る場合にのみ同じです。したがって、NR==FNR{a[$2]+=$3+$4; next}3番目と4番目の列の合計は、配列の2番目の列に関連する値に追加され、aこれは最初のファイルに対してのみ実行されます。これnextにより、次の行に移動し、現在の行の残りのスクリプトは実行されません。

{b[$2]+=$3+$4;}このファイルは、前のファイルが実行されておらず、2 番目のファイルを読み取る場合にのみ実行されます。配列に保存することを除いて、2番目のファイルの値と同じことを行いますb

すべての入力が終了すると、ブロックEND{}が実行されます。これはin内のすべてのキーに対して繰り返されa、in内のキーでもあり、bその値が同じでない場合はキーを印刷します。

関連情報