命令行下简单的检索
前段时间有这么个需求,两个文件,假设是tmp1和tmp2,tmp1里有服务器序列号和服务器主机名,如下:
a 1
b 2
c 3
d 4
e 5
f 6
g 7
tmp2里则是一些无序的序列号,如下:
d
c
e
f
a
g
b
现在需要做的是按tmp2里的顺序得到它们所对应的主机名。
对于这个需求,最开始想到的就是对tmp2里的每个序列号循环,每个循环里再遍历一次tmp1的内容,从而找到需要的主机名,不过这方法当文件很大时就很慢了。所以改进了一下,把tmp1存到一个hash里,然后遍历tmp2从hash里获得需要的东西。脚本如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | #!/usr/bin/perl use warnings; use strict; open(TMP1,"<tmp1") or die("error1\n"); my %hash; while(<TMP1>){ chomp(my $tmp = $_); my($index,$value) = split(/\s+/,$tmp); $hash{$index} = $value; } close(TMP1); open(TMP2,"<tmp2") or die("error2\n"); while(<TMP2>){ chomp(my $tmp = $_); print $hash{$tmp}."\n"; } close(TMP2); |
当然,这样还是麻烦了点,简单一点可以直接在命令行下就搞定了
for i in `cat tmp2` do grep $i tmp1 | awk '{print $2}' done

命令行下那个还是老问题:那可是两层循环呀,文件大了估计要等很久。。。
@zesheng
试了下果然是很慢,10万行数据,在perl里用双重循环用了12s,hash用了0.2s,命令行下循环用了4m多钟。perl的效率比shell要高很多
有点奇怪啊
open $fp, '< tmp1';
%t = map { chomp; split } ;
open $fp, '< tmp2;
print $_, "\n" foreach map { chomp; $t{$_} } ;
\;
把读文件符给吃掉了。。。
@monger
谢谢指点,以后多交流。