perl中grep用法总结 z
一) Grep函数
grep有2种表达方式:grep BLOCK LISTgrep EXPR, LISTBLOCK表示一个code块,通常用{}表示;EXPR表示一个表达式,通常是正则表达式。原文说EXPR可是任何东西,包括一个或多个变量,操作符,文字,函数,或子函数调用。LIST是要匹配的列表。grep对列表里的每个元素进行BLOCK或EXPR匹配,它遍历列表,并临时设置元素为$_。在列表上下文里,grep返回匹配命中的所有元素,结果也是个列表。在标量上下文里,grep返回匹配命中的元素个数。(二) Grep vs. loopsopen FILE "<myfile" or die "Can't open myfile:$!";print grep /terrorism|nuclear/i,<FILE>;;这里打开一个文件myfile,然后查找包含terrorism或nuclear的行。<FILE>;返回一个列表,它包含了文件的完整内容。可能你已发现,如果文件很大的话,这种方式很耗费内存,因为文件的所有内容都拷贝到内存里了。代替的方式是使用loop(循环)来完成:while ($line = <FILE>;) {if ($line =~ /terrorism|nuclear/i) { print $line }}上述code显示,loop可以完成grep能做的任何事情。那为什么还要用grep呢?答案是grep更具perl风格,而loop是C风格的。更好的解释是:(1)grep让读者更显然的知道,你在从列表里选择某元素;(2)grep比loop简洁。一点建议:如果你是perl新手,那就规矩的使用loop比较好;等你熟悉perl了,就可使用grep这个有力的工具。(三) 几个grep的示例1. 统计匹配表达式的列表元素个数$num_apple = grep /^apple$/i, @fruits;在标量上下文里,grep返回匹配中的元素个数;在列表上下文里,grep返回匹配中的元素的一个列表。所以,上述code返回apple单词在@fruits数组中存在的个数。因为$num_apple是个标量,它强迫grep结果位于标量上下文里。2. 从列表里抽取唯一元素@unique = grep { ++$count{$_} < 2 }qw(a b a c d d e f g f h h);print "@unique\n";上述code运行后会返回:a b c d e f g h即qw(a b a c d d e f g f h h)这个列表里的唯一元素被返回了。为什么会这样呀?让我们看看:%count是个hash结构,它的key是遍历qw()列表时,逐个抽取的列表元素。++$count{$_}表示$_对应的hash值自增。在这个比较上下文里,++$count{$_}与$count{$_}++的意义是不一样的哦,前者表示在比较之前,就将自身值自增1;后者表示在比较之后,才将自身值自增1。所以,++$count{$_} < 2表示将$count{$_}加1,然后与2进行比较。$count{$_}值默认是undef或0。所以当某个元素a第一次被当作hash的关键字时,它自增后对应的hash值就是1,当它第二次当作hash关键字时,对应的hash值就变成2了。变成2后,就不满足比较条件了,所以a不会第2次出现。所以上述code就能从列表里唯一1次的抽取元素了。2. 抽取列表里精确出现2次的元素@crops = qw(wheat corn barley rice corn soybean hayalfalfa rice hay beets corn hay);@duplicates = grep { $count{$_} == 2 }grep { ++$count{$_} >; 1 } @crops;print "@duplicates\n";运行结果是:rice这里grep了2次哦,顺序是从右至左。首先grep { ++$count{$_} >; 1 }@crops;返回一个列表,列表的结果是@crops里出现次数大于1的元素。然后再对产生的临时列表进行grep { $count{$_} == 2}计算,这里的意思你也该明白了,就是临时列表里,元素出现次数等于2的被返回。所以上述code就返回rice了,rice出现次数大于1,并且精确等于2,明白了吧? :-)3. 在当前目录里列出文本文件@files = grep { -f and -T } glob '* .*';print "@files\n";这个就很容易理解哦。glob返回一个列表,它的内容是当前目录里的任何文件,除了以'.'开头的。{}是个code块,它包含了匹配它后面的列表的条件。这只是grep的另一种用法,其实与 grep EXPR,LIST 这种用法差不多了。-f and -T匹配列表里的元素,首先它必须是个普通文件,接着它必须是个文本文件。据说这样写效率高点哦,因为-T开销更大,所以在判断-T前,先判断-f了。4. 选择数组元素并消除重复@array = qw(To be or not to be that is the question);@found_words =grep { $_ =~ /b|o/i and ++$counts{$_} < 2; }@array;print "@found_words\n";运行结果是:To be or not to question{}里的意思就是,对@array里的每个元素,先匹配它是否包含b或o字符(不分大小写),然后每个元素出现的次数,必须小于2(也就是1次啦)。grep返回一个列表,包含了@array里满足上述2个条件的元素。5. 从二维数组里选择元素,并且x<y# An array of references to anonymous arrays@data_points = ( [ 5, 12 ], [ 20, -3 ],[ 2, 2 ], [ 13, 20 ] );@y_gt_x = grep { $_->;[0] <$_->;[1] } @data_points;foreach $xy (@y_gt_x) { print "$xy->;[0],$xy->;[1]\n" }运行结果是:5, 1213, 20这里,你应该理解匿名数组哦,[]是个匿名数组,它实际上是个数组的引用(类似于C里面的指针)。@data_points的元素就是匿名数组。例如:foreach (@data_points){print $_->;[0];}这样访问到匿名数组里的第1个元素,把0替换成1就是第2个元素了。所以{ $_->;[0] <$_->;[1] }就很明白了哦,它表示每个匿名数组的第一个元素的值,小于第二个元素的值。而grep { $_->;[0] <$_->;[1] } @data_points; 就会返回满足上述条件的匿名数组列表。所以,就得到你要的结果啦!6. 简单数据库查询grep的{}复杂程度如何,取决于program可用虚拟内存的数量。如下是个复杂的{}示例,它模拟了一个数据库查询:# @database is array of references to anonymous hashes@database = ({name =>; "Wild Ginger",city =>; "Seattle",cuisine =>;"Asian Thai Chinese Korean Japanese",expense =>;4,music =>;"\0",meals =>; "lunchdinner",view =>; "\0",smoking =>;"\0",parking =>;"validated",rating =>;4,payment =>; "MCVISA AMEX",},# { ... }, etc.);sub findRestaurants {my ($database, $query) = @_;return grep {$query->;{city} ?lc($query->;{city}) eqlc($_->;{city}) : 1and$query->;{cuisine} ?$_->;{cuisine} =~/$query->;{cuisine}/i : 1and$query->;{min_expense} ?$_->;{expense} >;=$query->;{min_expense} : 1and$query->;{max_expense} ?$_->;{expense} <=$query->;{max_expense} : 1and$query->;{music} ? $_->;{music} :1and$query->;{music_type} ?$_->;{music} =~/$query->;{music_type}/i : 1and$query->;{meals} ?$_->;{meals} =~ /$query->;{meals}/i :1and$query->;{view} ? $_->;{view} :1and$query->;{smoking} ? $_->;{smoking} :1and$query->;{parking} ? $_->;{parking} :1and$query->;{min_rating} ?$_->;{rating} >;=$query->;{min_rating} : 1and$query->;{max_rating} ?$_->;{rating} <=$query->;{max_rating} : 1and$query->;{payment} ?$_->;{payment} =~/$query->;{payment}/i : 1} @$database;}%query = ( city =>; 'Seattle', cuisine=>; 'Asian|Thai' );@restaurants = findRestaurants(\@database, \%query);print "$restaurants[0]->;{name}\n";运行结果是:Wild Ginger上述code不难看懂,但仙子不推荐使用这样的code,一是消耗内存,二是难于维护了。(注,以上内容均源自bbs.chinaunix.net)
perl中grep用法总结 z相关推荐
- perl中grep用法总结
( 一) Grep函数 grep有2种表达方式: grep BLOCK LIST grep EXPR, LIST BLOCK表示一个code块,通常用{}表示:EXPR表示一个表达式,通常是正则表达式 ...
- Linux中grep用法(“或”、“与”)
1.普通用法 grep keyword 若果keyword中有空格 grep "keyword" 例如: ls | grep mp4 2."与"操作(其实就是多 ...
- shell中grep的用法
一:grep文本搜索 grep:强大的文本搜索工具(是一种"贪婪"的工具) 补充说明: grep (global search regular expression(RE) and ...
- perl中last的用法
在C语言中,如果想要退出一个循环,我们可以使用break.在perl中,没有beak这个关键字,但是perl却也提供了另外一个关键字,让程序从循环中跳出,那就是last.现在我们就看一下last的使用 ...
- [Perl系列—] 2. Perl 中的引用用法
Perl 中的引用,为什么要使用引用? 对于熟悉C语言的开发者来说, 指针这个概念一定不陌生. Perl 的引用就是指针,可以指向变量.数组.哈希表甚至子程序. Perl5中的两种Perl引用类型为硬 ...
- perl中的grep函数介绍
31 grep函数 (如果你是个的新手,你可以先跳过下面的两段,直接到 Grep vs.loops 样例这一部分,放心,在后面你还会遇到它) <pre> grep BLOCK LIST g ...
- linux中grep命令 菜鸟教程,linux grep正则表达式与grep用法详解
需要大家牢记:正则表达式与通配符不一样,它们表示的含义并不相同 正则表达式只是字符串的一种描述,只有和支持正则表达式的工具相结合才能进行字符串处理.本文以grep为例来讲解正则表达式. grep命令 ...
- linux中grep基本用法
grep 查找并且提取文件内容 常用的匹配模式 hello 包含字符hello ^hello 以字符串hello开头 hello$ 以字符串hello结尾 语法格式 grep "条件&quo ...
- linux系统grep用法,Linux系统中怎么使用grep命令?
在维护Linux系统时,我们常常需要在文本中搜索需要的东西,如果人为手动的去找那显然效率低下,那么如何才能快速找到所需要的文本呢?下面小编就以CentOS6.4系统为例为大家演示如何进行文本查找. 一 ...
最新文章
- 解决更新到os x10.11后openssl头文件无法找到的问题
- seo说_百度指数看世间沉浮_如何快速排名-互点快速排名_网站seo优化排名,网络推广的优化服务...
- 【Nexus3】使用-Nexus3批量上传jar包 artifact upload
- Gitlab的使用总结
- Linux系统非阻塞I/O select、poll和epoll非常好的两篇文章
- Java中常见异常及异常处理方式
- Matlab 向量的处理
- Openwrt Web gui LUCI 流程浅析
- 2020牛客暑期多校训练营The Flee Plan of Groundhog(树形DP)
- Flutter InkWell Ink组件
- java this final_JAVA中的this,final,surper的用法
- 为什么模电这么难学?一文带你透彻理解模电
- 微信小程序获取当前时间及获取当前日期
- 基于xc7k325t fbg900的IBRET的测试流程
- 【数学建模】2022亚太赛A题 结晶器熔炼结晶过程序列图像特征提取与建模分析
- 20230419心情随记
- TCL智能电视ROOT教程 附ROOT工具下载
- python经典类和新式类_python中经典类和新式类的区别
- 绝地求生服务器在线人数,《绝地求生:大逃杀》同时在线人数突破165万 官方就服务器问题向玩家致歉...
- 测试工程师「 面试题 」那点故事
热门文章
- linux根据端口限速,Linux 中限制网络带宽使用trickle或wondershaper
- ObjectARX中反应器的使用
- java导出excel插入图片
- 安卓开发之 在应用中使用数据库
- xbox手柄_请不要通过Xbox Live判断白人
- chrome表单自动填充默认样式-autofill
- 【AtCoder】AtCoder Grand Contest 046
- Python加密word文档
- java 对word加密_Word文档中怎样给文件信息加密?大神都这样操作,你还不知道?...
- winSocket第一步WSAStartup