- 论坛徽章:
- 0
|
sort,map的特別用法...
- #!/usr/bin/perl
- @by_uid = map { $_->;[0]} sort {$a->;[1] <=>; $b->;[1] } map { [$_,(split /:/)[2]] } <DATA>;;
- for(@by_uid){print ."\n";}
- __DATA__
- root:x:0:0:root:/root:/bin/bash
- bin:x:1:1:bin:/bin:/sbin/nologin
- daemon:x:2:2:daemon:/sbin:/sbin/nologin
- adm:x:3:4:adm:/var/adm:/sbin/nologin
- sync:x:5:0:sync:/sbin:/bin/sync
- shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
- halt:x:7:0:halt:/sbin:/sbin/halt
- mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
- ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
- nobody:x:99:99:Nobody:/:/sbin/nologin
- mailnull:x:47:47::/var/spool/mqueue:/dev/null
- rpm:x:37:37::/var/lib/rpm:/bin/bash
- ident:x:98:98:pident user:/:/sbin/nologin
- pcap:x:77:77::/var/arpwatch:/sbin/nologin
- sshd:x:501:501::/dev/null:/dev/null
- mysql:x:100:101:MySQL server:/var/lib/mysql:/bin/bash
- cnhackTNT:x:0:0::/home/cnhackTNT:/bin/bash
- chutium:x:504:504:Seraph Chutium:/home/chutium/:/bin/bash
复制代码
- @by_uid = map { $_->;[0]} sort {$a->;[1] <=>; $b->;[1] } map { [$_,(split /:/)[2]] } <DATA>;;
- 以下对上面的根据uid来排序的code做出解释:
- <DATA>;实际上可以看成一个数组,内容就是__DATA__下的那些,这里我们把它当作是@DATA这个数组(Apile原文里就是/etc下的passwd文件的内容)。
- map{[$_,(split /:/)[2]}从@DATA中取出每条数据,并对每条数据以 : 作为分割符分割,也就是 split(/:/,$_);
- 然后返回一个数组@_,以sshd:x:501:501::/dev/null:/dev/null为例,那么这个返回的数组中的一项可以看成:
- $_=['sshd:x:501:501::/dev/null:/dev/null','501'];
- 从上可看出这个$_是一个匿名的数组引用,他实际上包含两个部分,其中第二部分是uid,也就是$_->;[1]
- 现在@_中的内容变成了:
- ....前面的省略.....
- ['rpm:x:37:37::/var/lib/rpm:/bin/bash','37']
- ['ident:x:98:98:pident user:/:/sbin/nologin,'98']
- ['pcap:x:77:77::/var/arpwatch:/sbin/nologin','77']
- ['sshd:x:501:501::/dev/null:/dev/null','501']
- ....后面的省略.....
- 然后sort {$a->;[1] <=>; $b->;[1] }便是根据@_中的每项(实际上是数组引用)的第二部分uid的大小来排序,这里的sort排序是标准的方法,很多书里都有例子。
- 现在,经过上面的过程,数组@_中的内容已经以uid大小排好序了, 现在我们只要按@_排好的顺序读取每一项内容的第一部分,以
- ['sshd:x:501:501::/dev/null:/dev/null','501']为例,我们要取他的第一部分'sshd:x:501:501::/dev/null:/dev/null',也就是$_->;[0],并将其保存到数组@by_uid中就好了,而map { $_->;[0]}很好的完成了这项工作。
复制代码
实际上只要明掌握了map,sort的用法就能容易的理解上面算法的意思
下面是perlmonks.com上的一个sort的例子,简单却很好的完成了任务,你可以看看:
- #!/usr/bin/perl
- use strict;
- use vars qw(@results);
- @results = ("Bean Burrito|0.69|5",
- "Seven-Layer Burrito|1.39|8",
- "Pintos -n- cheese|0.59|0",
- );
- sub numerically_by_item
- {
- my($which)=@_;
- return sub { (split(/\|/,$a))[$which] <=>; (split(/\|/,$b))[$which] }
- }
- sub alpha_by_item
- {
- my($which)=@_;
- return sub { (split(/\|/,$a))[$which] cmp (split(/\|/,$b))[$which] }
- }
- my $sortby;
- print "Sorted by price\n";
- $sortby = numerically_by_item(1);
- print join("\n",sort $sortby @results);
- print "\n\n";
- print "Sorted by name\n";
- $sortby = alpha_by_item(0);
- print join("\n",sort $sortby @results);
- print "\n\n";
- print "Sorted by messiness\n";
- $sortby = numerically_by_item(2);
- print join("\n",sort $sortby @results);
- print "\n\n";
复制代码
请指教^-^ |
|