perl学习笔记-----------------------(6)

1.<STDIN>为行输入操作,但其实际上是对一个文件句柄(filehandle)的行输入操作(有<>表示)。本章后面将更多的介绍文
件句柄(filehandle)。
$line = <STDIN>; #读入下一行;
chomp($line); #去掉结尾的换行符
chomp($line=<STDIN>) #同上,更常用的方法

2.行输入操作在到达文件的结尾时将返回undef,这对于从循环退出时非常方便的:
while (defined($line = <STDIN>)) {
print “I saw $line”;
}
第一行代码值得仔细说明:我们将输入的字符串读入一个变量,检查其是否defined,如果是(意味着我们没有到达输入的
结尾),则执行while 的循环体。因此,在循环的内部,我们将看到每一行,一行接着一行。

3.在这种类型的循环中,你不能将chomp 操作插入条件表达式中,因此这通常是循环体的第一条语句。

4.
while (defined($_ = <STDIN>)){
print “I saw $_”;
}
这种简写只在特定的情况下有效,默认的情况下不会将一行读入变量$_。仅当while
循环的条件判断部分只包含行输入操作才有效。如果在条件判断部分还有别的内容,则上述简写无效。

5.在列表context 中使用行输入操作时,则会将所有的行(剩下的)当作一个列表,而每一行作为列表的一个元素:
foreach(<STDIN>){
print “I saw $_”;
}
同样,行输入操作和Perl 的默认变量$_没有必然的联系。在上例中,foreach 默认的控制变量为$_。因此,此循环将每一行 赋给$_。

6.在while 循环中,Perl 读入一行,将它赋给变量,然后进入循环。再回到开头,读入下一行。但 在foreach 循环中,由于行输入操作在列表的context 中使用,因为foreach 需要一个列表作为其参数。因此,它在循环执行 前会将所有的输入读入。这种区别在读入一个400MB 的web 服务器的log 文件时非常明显。通常使用while 循环是一种更 好的方法,因为它一次处理一行输入。

7.尖括号◆输入(diamond operator):<>。这种方法对于书写类似于标准Unix◆工具的程序非常有用。如果 想写一个Perl 程序,使它具有像cat, sed, awk, sort, grep, lpr, 以及许多别的应用程序类似的功能,则<>将帮上你的大忙。

8.当程序开始运行运行时,它有0 个或多个调用参数,这由此程序决定。这通常出现在shell 中,此列表由你命令行中输入的内容决定。在 后面将看到,调用程序可以使用许多字符串作为调用参数(invocation arguments)。由于它们经常出现在命令行中,因此有时亦被称作命 令行参数(command-line arguments)。
$ ./my_program fred barney betty

9.上述命令的含义是,运行my_program(在当前目录下),它将处理文件fred,再处理文件barney,最后是文件betty。 尖括号操作(<>)是一种特殊的行输入操作。其输入可由用户选择◆:
◆可能是从键盘,或者不是
while (defined($line = <>)){
chomp($line);
print “It was &line that I saw!\n”;
}
运行此程序,调用参数为fred, barney, betty,则结果大概如下:“It was [a line from file fred] (文件中fred 的一行)that I saw!”, “It was [another line from file fred](文件fred 中的另一行) that I saw!”,直到文件fred 的结尾。然后,将自动转到文件 barney,一行一行的输出,最后到文件betty。从一个文件到另一个文件之间没有空行,当使用<>时,就像输入的是一个大 文件一样。如果输入结束时,<>将返回undef。

9.当前的文件名字被保存在Perl 的特殊变量$ARGV 中。名字“-”代表某个文件,如果其为标准输入流输入

10.由于<>通常被用来处理所有的输入,因此在同一个序中重复使用是不正确的。如果在同一个程序中使用了2 次<>,特别是 在while 循环内第二次使用<>读入第一次<>的值,其结果通常不是你所希望的◆。根据我们的经验,当初学者在程序中使 用第二个<>,通常是想使用$_。记住,<>读入输入,但输入内容本身被存储在$_(默认的情形)。

11.打印数组和内插一个数组是不同的:
print @array; #打印出元素的列表
print “@array”; #打印一个字符串(包含一个内插的数组)
第一个语句打印出所有的元素,一个接着一个,其中没有空格。第二个打印出一个元素,它为 @array 的所有元素,其被存
在一个字符串中。也就是说,打印出 @array 的所有元素,并由空格分开◆。如果 @array 包含qw /fred barney betty /◆,则
第一个例子输出为:fredbarneybetty,而第二个例子输出为fred barney betty(由空格分开)

12.字符串包含换行符,如果想输出它们,通常:
print @array ;
如果不包含换行符,通常想加上一个:
print “@array\n”

13.通常,需要把程序的输出先缓存起来。将要输出的内容先缓存起来,等到有足够的内容再输入,而非立刻就输出。例如, 假设要把输出的内容存入磁盘,如果有一个或两个字符就立刻输出到磁盘中,这将非常缓慢和低效。一般,先将要输出的 内容存入一个缓存(buffer)中,当缓存满时,再将其输出。

14.Perl 的另一个规则是:如果调用print 的方法看起来是函数调用,则它就是函数调用

15.如果你的程序需要你立刻输出,则希望每一次print 时,就输出。参照Perl 的帮助手册,了解更多的关于控制缓存的信息。 由于print 需要一些输出的字符串列表,则其参数是作为列表context 来求值的。由于<>操作返回的是列表,则它们可很好 的一起工作:
print <>; # ‘cat’的源程序
print sort <>; #‘sort’的源程序

16.print 返回 值为true 或者false,表明print 成功或者失败。通常是成功的,除非遇到I/O 错误,因此,下面语句中$result 的值通常为1:
$result = print(“hello world\n”);

17.printf 函数有一个格式字符串(format string),后接需要输出的字符串列表。格式◆字符串,是一个模板,它规定输出的格式: ◆这里,我们按照一般意义来使用“format”。Perl 有报告生成(report-generating)的功能,称为“formats”。现在我们不打算讨论它。
printf “Hello, %s; your password expires in %d days!\n”, $user, $days_to_die;
格式字符串中有一些被称作格式符(conversion)的东西;每一个格式符由百分号(%)开头,由字母结束
后面元素个数和格式符的个数是一致的。如果不等,则不能正确执行。上述代码中后
面有2 个元素,有2 个格式符。因此输出类似于:
Hello, meryn; your password expires in 3 days!

18.要输出数字,通常使用%g◆,它将根据需要自动选用浮点数,整数,或者指数:
.%d 为十进制◆整数,根据需要而截尾:
%x 是针对十六进制的,%o 是针对八进制的。
print “in %d days!\n”,17.85; #in 17 days!

20.如果宽度值为负数,则为左对齐(对于所有的格式符)

21.%f 根据需要进行截尾,你可以设置需要几位小数点后面的数字

22.要输出一个百分号,可以使用%%,它不会使用后面列表中的元素

23.通常,不会将数组作为参数传递给printf。因为数组可能含有任意数量的元素,而某个给定的格式字符串仅对固定数量的参数有效:如果格式化字符串中有3 个格式符,则对应3 个元素。 但没有理由因为表达式可以是任意的,就不能指定一个格式字符串。这需要一些技巧才能使之正常工作,如果将格式存入 变量中可能会带来方便(特别是调试的时候):
my @items = qw( wilma dino pebbles );
my $format = “The items are:\n”. (“%10s\n”x @items);
## print“the format is >>$format<<\n”; #用于调试
printf $format, @items;
或者
printf“The items are:\n”. (“%10s\n”x @items), @items;

24.文件句柄(filehandle)是Perl 程序I/O 连接的名字,是Perl 和外界的纽带。也就是说,它是连接的名字,而非文件的名字。

25.文件句柄的命名规则和Perl 中其它标识符一样(由字母,数字,下划线组成,但不能由数字开头);由于没有任何的前缀符, 这可能和现在或者将来的保留字,标签混淆。因此,和标签一样,Larry 推荐文件句柄的所有字母均大 写。

26.Perl 自身有六个文件句柄:STDIN,STDOUT,STDERR,DATA,ARGV,ARGVOUT◆。虽然可以任意给文件句柄命名, 但不能选择上面六个。

27.当程序运行时,STDIN 连接Perl 当前处理的部分和其他输入来源,其一般被称作标准 输入流。通常,是指键盘,除非指定了别的输入源,如文件或者另一个程序的输出,通过管道(pipe)◆。STDOUT 是标准 输出流。默认情况,这是指用户的显示屏,但可以将其输出到文件,或者另一个程序中,我们将很快看到。

28.:STDERR。标准输出可以输出到另一个程序或者文件, 错误可以输出到用户指定的任何地方。默认情况下,错误将输出到用户的显示屏◆,但用户可能把错误输出到文件中,如 下面的命令:
◆通常,错误是不会被缓存的。这就使说,如果标准输出流和标准错误都是输出到同一个地方(如显示器),则错误通常会出现在普通输
出的前面。例如,你的程序输出普通文件的一行,和除以0,则通常会先显示除以0 的(错误)信息,然后才是文件的内容。
$netstat | ./your_program 2>/tmp/my_errors

29.当需要其它的文件句柄时,使用open 操作通知Perl,Perl 再请求操作系统来建立同外部的连接。下面是一些例子:
open CONFIG, “dino”;
open CONFIG, “<dino”;
open BEDROCK, “>fred”;
open LOG,“>>logfile”;
第一例中打开了一个名为CONFIG 的文件句柄,它指向dino 文件。也就是说,文件dino 将被打开,其所包含的数据通过 CONFIG 传给程序。这和从文件中取数据,也可以通过STDIN 得到是类似的,如果在命令行中使用了shell 重定位操作如 <dino。第二例和第一例类似;它和第一例是一样的,只是< 明确的指明了“使用这个文件进行输入操作”,虽然默认的 情况就是输入(没有<)

30.可以在文件名的地方使用任何的标量表达式,虽然通常你可能不想这样做:
my $selected_output = “my_output”;
open LOG,“> $selected_output”;
注意大于号后面的空格。Perl 会忽略它◆,但它防止可能出现的异常情况。如,当$selected_output 为“>passwd”,则它将 变成追加。

31.Perl 的新版本中(从Perl5.6 开始),open 支持“3 参数”类型:
open CONFIG, “<”, “dino”;
open BEDROCK, “>”, $file_name;
open LOG, “>>”, &logfile_name();

32.当结束一个文件句柄时,你可以如下这样关闭它: close BEDROCK;
当关闭文件句柄时,Perl 将告诉操作系统已经结束了对此数据流的操作,因此应当将输出的数据写到磁盘中,可能某人正 在等待使用它◆。如果程序重新打开它(也就是说,使用open 重新打开此文件句柄),或者退出程序,Perl 将自动关闭 文件句柄。

33.如果希望程序更加整洁,则每一个open 都应当使用一个close。通常,最好在不使用一个文件句柄时就立刻将它关闭,无论程序是否立即结束

34.die 函数将打印出你给它的消息(利用标准错误流),并确保程序退出时为非零(nonzero)的退出状态(exit status)。

35.
if(!open LOG, “>>logfile”){
die “Cannot create logfile:$!”;
}
如果open 失败,则die 将结束程序,并告诉你不能创建logfile。$!是系统产生的一些可读的 信息。通常,当系统拒绝了我们的请求(如打开文件),$!将告诉你原因 36.如果使用die 来表明错误,但此错误不是系统请求失败引起的,则不要使用$!,因为其包含的信息和 实际的问题无关

37.如果命令行中的参数少于2 个,上述程序将打印出此错误并退出。他不会打印出程序的名字和程序出错的行号,这些信息 对用户是没有用的;毕竟这是用户的错误。作为一般规则,如果用法错误则在消息后面加上换行符;如果是其它错误,需 要利用它来调试,则不要加上换行符

38.warn 函数像die 那样工作,除了最后一步,它不会从程序中退出。它也能加上程序的名字和行号,并把消息输出到标准错 误那里(standard error),和die 一样。

39.当某个文件句柄被打开进行输入时,可以像从STDIN 中输入一样。例如,读入Unix 中的密码文件:
if(! open PASSWD, “/etc/passwd”){
die “How did you get logged in?($!)”;
}
while(<PASSWD>){
chomp;
...
}
在本例中,die 后面的消息使用了$!。它被括号括起来了。如你所知的, “行输入操作(line-input operator)”由两部分组成; 尖括号(<>,真正的行输入操作(line-input operator))和尖括号中的文件句柄。

40.写出(>)或追加的(>>)的文件句柄,可以和print 或printf 结合使用,如:
print LOG “Captain’s log, stardate 3.14159\n”; #输出到LOG 中
printf STDERR “%D percent complete.\n”, $done/$total * 100;
注意到文件句柄和要打印的内容之间没有逗号了吗◆?如果使用括号,看起来会非常古怪。下面的两种写法都是正确的:
printf (STDERR “%d percent complete.\n”, $done/$total * 100);
printf STDERR (“%d percent complete.\n”, $done/$total * 100);

转载于:https://my.oschina.net/u/2291665/blog/884995

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值