log file1包含昨天访问过的客户(姓名,ID,日期)的记录 log file2包含今天访问过的客户(姓名,ID,日期)的记录
您如何展示昨天访问但未访问的客户?
约束是:不要使用辅助数据结构,因为文件包含数百万条记录。 [所以,没有哈希] 有没有办法使用Unix命令?
答案 0 :(得分:2)
示例,但请查看comm
的手册页以获取所需的选项。
comm -2 <(sort -u yesterday) <(sort -u today)
您可以使用的其他工具是diff
diff <(sort -u yesterday) <(sort -u today)
答案 1 :(得分:0)
客户是否通过身份识别?是int还是long?如果这两个问题的答案都是肯定的,那么一个包含10,000,000个整数的数组不应该超过10M * 4 = 40MB的内存 - 对于体面的硬件来说并不是什么大不了的事。只需对它们进行排序和比较
顺便说一句,在我的机器上用10M随机整数排序一个数组不到2秒 - 再一次,没什么好害怕的。这是一些非常简单的Java代码:
public static void main(final String args[]) throws Exception {
// elements in each log file
int count = 10000000;
// "read" our log file
Random r = new Random();
int[] a1 = new int[count];
int[] a2 = new int[count];
for (int i = 0; i < count; i++) {
a1[i] = Math.abs(r.nextInt());
a2[i] = Math.abs(r.nextInt());
}
// start timer
long start = System.currentTimeMillis();
// sort logs
Arrays.sort(a1);
Arrays.sort(a2);
// counters for each array
int i1 = 0, i2 = 0, i3 = 0;
// initial values
int n1 = a1[0], n2 = a2[0];
// result array
int[] a3 = new int[count];
try {
while (true) {
if (n1 == n2) {
// we found a match, save value if unique and increment counters
if (i3 == 0 || a3[i3-1] != n1) a3[i3++] = n1;
n1 = a1[i1++];
n2 = a2[i2++];
} else if (n1 < n2) {
// n1 is lower, increment counter (next value is higher)
n1 = a1[i1++];
} else {
// n2 is lower, increment counter (next value is higher)
n2 = a2[i2++];
}
}
} catch (ArrayIndexOutOfBoundsException e) {
// don't try this at home - it's not the pretties way to leave the loop!
}
// we found our results
System.out.println(i3 + " commont clients");
System.out.println((System.currentTimeMillis() - start) + "ms");
}
结果
// sample output on my machine:
46308 commont clients
3643ms
如您所见,每个日志中的10M记录非常有效
答案 2 :(得分:0)
我个人打算创建一个数据结构和访问记录,但是,我也可以看到你是怎么做的。
在伪代码中,它看起来像python,但可以用perl或shell脚本重写,或者......
import subprocess
import os
for line in fileinput.input(['myfile'])::
# split out data. For the sake of it I'm assuming name\tid\tdate
fields = line.split("\")
id = fields[1]
grepresult = subprocess.Popen("grep \"" + id + "\" file1", shell=True, bufsize=bufsize, stdout=PIPE).stdout
if len(grepresult) == 0:
print fields # it wasn't in field1
这不是完美的,没有经过测试,所以请妥善处理,但它为您提供了如何使用unix命令的要点。也就是说,正如sfussenegger指出C / C ++,如果你正在使用它应该能够处理相当大的文件。
免责声明:这是一个不太整洁的解决方案(反复调用grep)以匹配问题的要求。如果我这样做,我会使用C.