perl语言——输入与输出

1. 读取标准输入 < STDIN>

1
2
3
4
5
6
7
# 从控制台读取信息,并打印出来:
$line = <STDIN>;
print $line;
# 不停打印
while(<STDIN>) {
print $_; # 默认将标准输入的内容保存在$_变量中
}

2. 钻石操作符输入 <>

通过钻石操作符<>来读取文件的内容,使用时将要打开的文件名作为参数写在命令行中,如下

1
perl pro.pl filename

<>会读取文件中的内容,如果写了多个文件名,那么逐个打开文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 文件内容 command.log
first line
second line
third line
# perl 程序 pro.pl
while($line=<>) {
print $line;
print "ok\n";
}
# 在命令行中键入 perl pro.pl command.log
# 输出
first line ## 可以看到<>操作符逐行读取文件的内容保存在$line变量中
ok
second line
ok
third line
ok
#####################
while(<>) {
print $_;
print "ok\n";
}
## 输出一样,<>默认存在$_中

3. 调用参数 ——@ARGV数组

上面将的钻石操作符,其实不是直接来检查命令行的参数。命令行的参数先传给一个列表@ARGV,@ARGV中保存命令行中的参数成员

所以上面的程序也可以写成

1
2
3
4
5
6
7
@ARGV = 'command.log';
while($line=<>) {
print $line;
print "ok\n";
}
## 如果要打开多个文件
@ARGV = qw/file1 file2 file3/; ## qw// 返回列表

我们可以从命令行中向文件里传递参数,比如文件名,或者其他影响程序运行的参数。命令行中的参数保存在数组@ARGV中。

1
2
3
4
[command_line]$ pro.pl var1 var2 #从命令行向文件pro.pl传入了两个参数var1,var2
## 在文件pro.pl中使用传入的参数
$VAR1 = $ARGV[0];
$VAR2 = $ARGV[1];#把参数从数组@ARGV中提取出来

4. 输出到标准输出

标准输出就是< STDOUT>,默认print会输出到这,< STDOUT>默认对应的是控制台

1
2
3
4
5
6
7
8
9
10
print "this is a test\n";
# 也可以输出多个
print $val1,$val2,"hello";
## 对于列表输出
@list = qw/this is a test/;
print "@list\n";
print @list,"\n";
## 输出
this is a test ## 结果不言而喻,第二种输出都堆到一起了
thisisatest

如果手动指定输出到命令行。

1
2
print <STDOUT>,”hello"; // 这里的逗号是必须有的。
print STDOUT "hello\n"; // 这么写不需要逗号。

下面输出到文件的时候,不能写逗号,要用空格。

5. 格式化输出printf

这种类似于C中的, ** printf “格式字符串”,数据列表**

由%s,%d,%f等,还有%g自动选择整数浮点数还是指数形式

print没有这个功能。

1
2
3
4
5
6
7
8
printf "%s %s\n","hello","world";
printf "%4.2f\n",12.222;
hello world
12.22
## 也可以将格式字符串写成变量
$format = "%s %s\n";
printf $format,"hello","world";

在打印的时候动态生成格式字符串

1
2
3
4
5
6
@list = qw/apple banana pear/;
$format = "list have ".("%6s " x @list);
printf $format,@list;
# 输出
list have apple banana pear
.点号将字符串连接起来,x字符是将字符串复制多少份 ,@List用在这个标量环境中返回元素个数

6. 输入输出流定向 < 和 >

原来的标准输入< STDIN>是从控制台读入,< STDOUT>输出到控制台,但是可以通过标识符“<”和”>”来重新定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 # command.log 文件内容
first line
second line
third line
# pro.pl
while($line = <STDIN>) {
print $line;
}
# 命令行键入
perl pro.pl < command.log # <STDIN>是从command.log文件中读入
# output
first line
second line
third line
# 同理 > 是将<STDOUT>指向某个文件,而不是控制台

7. 文件句柄 open close

文件句柄是裸字,没有$这个美元符号

1
2
3
4
5
open FILE1,'file';
open FILE2,'> file1';
open FILE3,'< file2';
open FILE4,'>> file3'; # 以追加输入的方式打开文件
close FILE1;

8. 使用文件句柄对文件输入输出

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# command.log 文件内容:
first line
second line
third line
# pro1.pl perl程序文件内容:
open CMD,"< command.log";
$line = <CMD>; # <CMD>只能读取一行
print $line;
close CMD;
# output:
first line # 只输出一行,
######################
#如果想要读取多行,如下写
# pro2.pl perl程序文件内容:
open CMD,"< command.log";
$line = join "",<CMD>; # 将所有的行连接成一个大的字符串
print $line;
close CMD;
#output:
first line
second line
third line
######################
# pro3.pl 也可以这么写,while循环输出所有行
open CMD,"< command.log";
while($line=<CMD>) {
print $line;
}
close CMD;

9. 改变默认文件的输出句柄 select

比如 print 默认输出到< STDOUT>,到控制台

1
2
3
4
5
6
7
open fp,'> a.log';
select fp;
print "TO FILE!!";
## 输出到了文件a.log中
select STDOUT;
print "TO STDOUT!!\n";
# 输出到控制台

10. 直接输出到文件句柄中

直接将字符串输出到文件句柄

1
2
3
open fp,'> a.log';
print fp "TO FILE!!\n"; # 注意格式,fp之后是空格
## 输出到了文件a.log中

这里文件句柄没有<>这个符号,有的话出错。

11. 将文件句柄保存在变量中

1
2
3
4
5
my $val_fh;
open $val_fh '<','file1';
# 或者写成一句
open my $val_fh '<','file1';
print <$val_fh>; #使用

12. 有问题的文件句柄

​ perl程序是不能打开文件的,需要操作系统代劳,如果操作系统权限不足,那么文件就打开失败。如果试图从有问题的文件句柄中读数据,会直接读到文件结尾;如果写,数据被丢弃。

​ 在编译的时候加-w或-warning选项会报出警告,但也可以在程序中规避这种错。open函数执行完会返回一个值,如果打开成功返回真,打开失败返回假。

1
2
3
if(! open fp,'> a.log') { # open返回假则执行if函数
## 操作失败
}

13. die处理致命错误

die可以使程序在发生异常或致命错误(比如除以零,子程序未定义,不合法的正则表达式等)的时候停止程序执行,并输出警告信息。

die函数执行时,会将程序员指定的信息输出到标准错误输出流中,并立即终止当前perl程序的执行,是终止整个perl文件程序,而不是单独的某个子程序。

1
2
3
4
if(! open fp,'> a.log') { # open返回假则执行if函数
die "cannot open file $!";
}
# 变量$!中包含系统错误的解释性信息,便于差错

如果在die后字符串中加了 \n ,则不会打印行号和文件名等信息。

1
2
3
if(@ARGV<2) {
die "not enough arguments\n"
}

14. 自动检测致命错误

在perl5.10中使用 use autodie; 会自动在open函数失败的时候返回错误信息。

15. 读取文件中的某些行保存在新文件中

从info.log文件中读取有”sequence”单词的行,将这些行保存在新的文件info.out文件中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
open f0,'< info.log';
open f1,'> info.out';
print f1 ""; #用’>'方式打开info.out文件,写入空将文件info.out清空
close f1;
open f1,'>> info.out'; #以递增的方式打开info.out

while($line=<f0>) {
# 从行首\A匹配到行尾\Z,\Z表示行尾,在它之后也可以有换行符。
# 将匹配到的值保存在列表中
push @l,($line =~ m/(?<var>\A.+sequence.+\Z\n)/);
print f1 $l[0];
pop @l;
}
close f0;
close f1;

# 也可以这样写
# $line =~ m/(?<var>\A.+sequence.+\Z\n)/;
# push @l,$1;
# print f1 $l[0];
# pop @l;