perl-读取
好久没有学perl了,最近python基础已经学完了。然后在学模块,模块也不是一会能弄懂的,所以就抽空学下perl,因为最近发现shell的一个缺点,就是不能跨平台,而我想写的脚本又要支持windows,所以fighting!
夸奖与吐槽:其实shell是真的好,写习惯了shell,再去用python或者perl时,就觉得有点麻烦。比如说读文件,修改文件,格式化等等cat,grep,sed,awk,wc,tr,xargs等等用的真的是舒服,组合一下,一两行就能搞定很多事情,根本不需要去写个函数啥的。但是在写一些较大的数据处理时,还是会觉得shell有些力不从心,比如说,就我了解的shell,就一个数组,然后没了。在涉及二维数组的时候吧,有时候用的确实麻烦,而且最多写写多进程,也没法写多线程,再一个就是不能跨平台了。好了,本来是perl的,怎么说了这么多shell
读取输入
1 | # 将标准输入读入到标量变量中 |
使用my
表示私有变量。这里使用到了特殊的文件句柄STDIN
,而符号<>
被称为diamond operation,可以读取所有的输入(包括文件)。而STDIN
就是默认的一个标准输入的句柄,句柄可以理解为一个变量,用来操作传入的数据。
scalar读取的就是一个字符串,回车结束。可以用函数chomp()
来去掉换行符,括号不是必须的
1 | eg: |
array读取的是一个数组,ctrl+d结束。之前写shell的时候,读取了一些列参数,但是想如果读取到-p(指定进程数),这是就自动加上一个-q参数,表示quiet。但是shell读到的数据并不是一个列表,所以不能将这个参数加上去。除非写个循环转列表,但是有点麻烦,如果用perl来写就简单多了。
1 | # 这么写是无法得到结果的,why? |
读取文件
open()
函数
open(filehandle,mode,filename)
Filehandle
that associates with the fileMode
: you can open a file for reading, writing or appending.Filename
: the path to the file that is being opened.
mode | operand | description |
---|---|---|
read | < | 只读 |
write | > | 文件存在会覆盖,不存在则创建 |
append | >> | 追加 |
close()
函数
文件打开之后就需要关闭,如果忘记关闭,perl也会自动关闭。但是这样不好,你懂得。
1 | #!/usr/bin/perl |
句柄要大写,小写的话虽然会执行,但是会报错,而且需要使用引号括起来。
or die $!
的写法,如果文件不存在则给出错误提示。
- First, we used the
open()
function to open a file for reading. - Second, the syntax
while()
is equivalent towhile(defined($_ = )
. We read a line from a file and assigned it to the special variable$_
. The loop is terminated when the end of the file reached. - Third, we displayed each line of the file by passing the variable
$_
to theprint
function.*
简化
1 | #!/usr/bin/perl |
执行它既可以读取标准输入,也可以在后面输入文件名,来读取多个文件内容。
这就是<>
diamond operation的魅力。
无论是在perl还是python中,读取一个文件都是需要写函数来获得的,还需要关闭,看着比shell复杂,实则这 告诉了我们一个道理,读取文件本来就不是很随意的一件事,就好像shell写多了,忽略了这一点。我发现不论是我写的脚本,还是其它人写的。完全没有考虑到效率问题。频繁的读取关闭文件是一件很浪费时间的事,因为硬盘的读取速度太慢,这也是为什么我们写的脚本执行慢的一个原因吧。所以要将需要从文件中读取的数据一次性读入内存中,然后使用。