AWKを使用してマップファイルでロードされたファイルを照会する方法[閉じる]

AWKを使用してマップファイルでロードされたファイルを照会する方法[閉じる]

私は2つのログファイル(In.logとOut.log)間の参照を関連付けるためにUbuntuでawkを使用しています。期待どおりに動作しますが、Out.logのサイズが増加(〜Kライン)され、処理時間も増えます!したがって、ディスクアクセスを減らすためにMAPFILEコマンドまたは同様のコマンドを使用して、ループの前にこのOut.logファイルをメモリに一度ロードできるかどうか疑問に思いましたが、有用な例を見たことがありません。どんな提案がありますか?

入力ログ:

2016-10-20 19:20:00,IN,DEU00000000159560100
2016-10-22 19:22:20,IN,DEU00000000159560511
2016-10-24 19:24:20,IN,DEU00000000159560382
2016-10-26 19:26:20,IN,DEU00000000159560609
2016-10-28 19:28:20,IN,DEU00000000159560809

出力ログ:

2016-10-20 19:20:30,OUT,DEU00000000159560100
2016-10-21 19:21:30,OUT,DEU00000000159560510
2016-10-22 19:22:30,OUT,DEU00000000159560511
2016-10-23 19:23:30,OUT,DEU00000000159560381
2016-10-24 19:24:30,OUT,DEU00000000159560382
2016-10-25 19:25:30,OUT,DEU00000000159560195
2016-10-26 19:26:30,OUT,DEU00000000159560609
2016-10-27 19:27:30,OUT,DEU00000000159560433
2016-10-28 19:28:30,OUT,DEU00000000159560809
2016-10-29 19:29:30,OUT,DEU00000000159560694

現在のスクリプト:

cat IN.LOG | while read -r Line
do
    Reference=$(cut -f3 -d',' <<< $Line)
    TimeStampIn=$(cut -f1 -d',' <<< $Line)
    TimeStampOut=$(awk -F',' -v Ref=$Reference '$3==Ref {print $1; exit} ' OUT.LOG)
    echo "$Reference,$TimeStampIn,$TimeStampOut"
done

ベストアンサー1

次のコマンドだけが必要ですawk

awk -v reflog=OUT.LOG '
    BEGIN{
      FS=OFS=",";
      while((getline <reflog) > 0) refs[$3]=$1;
      close(reflog)
    }{
      print $3,$1,refs[$3] ? refs[$3] : "not found"
    }' IN.LOG

または、join以下のユースケース用に特別に設計されたものを使用してください。

join -t, -j 3 -o 0,1.1,2.1 -a 1 -e "not found" \
  <(sort -t, -k3 IN.LOG) <(sort -t, -k3 OUT.LOG) \
  | sort -t, -k2

join入力ファイルは「結合列」に基づいてソートする必要があります。これが、2つのログファイルを最初に参照列に基づいてソートしてから、出力を日付別にソートする理由です。

両方のソリューションは異なる動作をします。OUT.LOGの一意でない参照について。awkOUT.LOGの重複参照は無視されますが(最後の参照が優先)、joinすべての一致が印刷されます。また、-a 2コマンドに追加するとjoin印刷されます。みんなペアリングできない回線です。

おすすめ記事