私は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の一意でない参照について。awk
OUT.LOGの重複参照は無視されますが(最後の参照が優先)、join
すべての一致が印刷されます。また、-a 2
コマンドに追加するとjoin
印刷されます。みんなペアリングできない回線です。