我在 Ubuntu 上使用 awk 来关联两个日志文件(In.log 和 Out.log)之间的引用。它按预期工作,但 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
需要对输入文件进行排序(按“连接列”)。这就是为什么我们先按引用列对两个日志文件进行排序,然后再按日期对输出进行排序。
两种解决方案的行为不同关于 OUT.LOG 中的非唯一引用。awk
会忽略 OUT.LOG 中的重复引用(最后一个获胜),但join
会打印所有匹配项。此外,如果您添加-a 2
到命令中join
,它会打印全部不可配对的线路。