我需要解析一个大型日志文件(平面文件),其中包含两列值(列A,列B)。
两个列中的值都是重复的。 我需要为每个唯一的列A值找到一组列B值。
这可以使用Unix shell命令完成,还是需要编写任何Perl或Python脚本? 有哪些方法可以做到这一点?
示例:
xxxA 2
xxxA 1
xxxB 2
XXXC 3
XXXA 3
xxxD 4
输出:
xxxA - 2,1,3
xxxB - 2
xxxC - 3
xxxD - 4
我需要解析一个大型日志文件(平面文件),其中包含两列值(列A,列B)。
两个列中的值都是重复的。 我需要为每个唯一的列A值找到一组列B值。
这可以使用Unix shell命令完成,还是需要编写任何Perl或Python脚本? 有哪些方法可以做到这一点?
xxxA 2
xxxA 1
xxxB 2
XXXC 3
XXXA 3
xxxD 4
xxxA - 2,1,3
xxxB - 2
xxxC - 3
xxxD - 4
将Perl的“一行代码”扩展到适合窗口的大小:
$ perl -F -lane '
$hash{ $F[0] }{ $F[1] }++;
} END {
for my $columnA ( keys %hash ) {
print $columnA, " - ", join( ",", keys %$hash{$columnA} ), "\n";
}
'
def parse_the_file():
lower = str.lower
split = str.split
with open('f.txt') as f:
d = {}
lines = f.read().split('\n')
for A,B in [split(l) for l in lines]:
try:
d[lower(A)].add(B)
except KeyError:
d[lower(A)] = set(B)
for a in d:
print "%s - %s" % (a,",".join(list(d[a])))
if __name__ == "__main__":
parse_the_file()
a = lower(A)
。
- 我使用了一个函数,因为在Python中访问局部变量比访问全局变量更有效。
- 这些性能提示中的一些来自here。xxxd - 4
xxxa - 1,3,2
xxxb - 2
xxxc - 3
您可以使用这个简单的 multimap:
class MultiMap(object):
values = {}
def __getitem__(self, index):
return self.values[index]
def __setitem__(self, index, value):
if not self.values.has_key(index):
self.values[index] = []
self.values[index].append(value)
def __repr__(self):
return repr(self.values)
看它如何运作:http://codepad.org/xOOrlbnf
key in dict
,在您的情况下是if not index in self.values:
;而且OP想要集合,不是列表。 - PaulMcG简单的 Perl 版本:
#!/usr/bin/perl
use strict;
use warnings;
my (%v, @row);
foreach (<DATA>) {
chomp;
$_ = lc($_);
@row = split(/\s+/, $_);
push( @{ $v{$row[0]} }, $row[1]);
}
foreach (sort keys %v) {
print "$_ - ", join( ", ", @{ $v{$_} } ), "\n";
}
__DATA__
xxxA 2
xxxA 1
xxxB 2
XXXC 3
XXXA 3
xxxD 4
没有关注变量名称。从例子中我看到它们不区分大小写。
使用 Perl 单行命令:
perl -lane'$F[0]=~s/.../lc$&/e;exists$s{$F[0]}and$s{$F[0]}.=",$F[1]"or push@v,$F[0]and$s{$F[0]}=$F[1]}{print"$_ $s{$_}"for@v'
$F [0] =〜s / ... / lc $&/ e; ,或者使用 $ F [0] = lc $ F [0]; 或 $ F [0] = uc $ F [0]; ,如果您可以将键统一为小写或大写。
f = """xxxA 2
xxxA 1
xxxB 2
XXXC 3
XXXA 3
xxxD 4"""
d = {}
for line in f.split("\n"):
key, val = line.lower().split()
try:
d[key].append(val)
except KeyError:
d[key] = [val]
print d
Python
d.setdefault(key, []).append(val)
来避免使用try/except。 - nmichaels
while() {
($key, $value) = split / /, $_;
$hash{lc($key)} = 1;
push(@array, "$key$value");
}
foreach $key (sort keys %hash) {
@arr = (grep /$key/i, @array);
chomp(@arr);
$val = join (", ", @arr);
$val =~ s#$key##gi;
print "$key\t$val\n";
}