第五章 输入与输出
while(defined($line = <STDIN>)) #defined (xxx) xxx为undef则为假,否则为真
{
print "I saw $line";
}
while(<STDIN>) #while是一次读取一行,下次读取会忽略上一行,所以最好写while循环
{
print "I saw $_;";
}
foreach (<STDIN>) #一下全部读出<STDIN>或者是文件内容,然后再一行行分析
{
print "I saw $_";
}
while(defined($line = <>)) #钻石操作符,是从命令行得到参数:$perl my_program.pl fred beny good
{
chomp($line); #则钻石操作符逐行从fred取出内容,然后,fred读到末尾后,再读beny,good直到读到最后
print "It was $line that I saw!\n"; #文件名my_program.pl存在于$1中
}
while(<>)
{
chomp;
print "It was $_ that I saw\n";
}
@ARGV = qw#larry moe curly#; #强制让钻石操作符只读取这三个文件
while(<>)
{
chomp;
print "$_\n";
}
print <>; #相当于unix下的cat命令
print sort <>; #相当于unix下的sort命令
数组和printf函数:
my @items = qw(wilma dino pebbles);
my $format = "The items are:\n".("%10s\n" x @items);
printf $format, @items;
printf "The items are:\n". ("%10s\n" x @items), @items;
print "\n";
$cat fred barney | sort | ./your_program | grep something | lpr
$netstat | ./your_program 2>/tmp/my_errors
文件句柄:
open CONFIG, "dino"; #使用文件
open CONFIG, "<fred"; #只读
open BEDROCK, ">fred"; #写入,当文件有内容时,就会覆盖原内容
open LOG, ">>logfile" #追加内容到logfile
my $selected_out = "my_output";
open LOG, "> $selected_output";
新版perl 5.6以后,文件句柄的写法:
open CONFIG, '<', "dino";
open BEDROCK, ">", $file_name;
open LOG, '>>', &logfile_name();
open CONFIG, '<:encoding(UTF-8)', 'dino';
open BEDROCK, '>:encoding(UTF-8)', $file_name;
open LOG, '>>:encoding(UTF-8)', &logfile_name();
$% perl -MEncode -le "print for Encode->encodings(':all')"
以二进制方式读写文件句柄:
binmode STDOUT, ':encoding(UTF-8)';
binmode STDIN, ':encoding(UTF-8)';
有问题的文件句柄:
my $success = open LOG, '>>', 'logfile'; #捕获返回值
if(! $success)
{
#open 操作失败
}
关闭文件句柄:
close LOG;
用die处理致命错误:
die函数会输出你指定的信息到专为这类信息准备的标准错误流中,并且让你的程序立即终止并返回不为零的退出码
if (! open LOG, '>>', 'logfile')
{
die 'Cannot create logfile: $!';
}
自动检测致命错误:
use autodie;
open LOG, '>>', 'logfile';
使用文件句柄:
if(! open PASSWD, "/etc/passwd")
{
die "How did you get logged in? ($!)";
}
while(<PASSWD>)
{
chomp;
}
print LOG "Captain's log, stardate 3.14159\n"; #输出到文件句柄LOG
print STDERR "%d percent complete.\n", $ddone/$total*100;
句柄和输出之间没逗号,别人说这叫间接对象
改变默认的文件输出句柄:验证并不能使用,在mac os下
默认情况下,数据时输出到STDOUT的,即输出到屏幕,可以通过select函数可以选择输出方向
select LOG;
$| = 1; #特殊变量$|设定为1,就会使当前的默认文件句柄在每次进行输出后立即刷新到缓冲区,所以如果要让输出的内容立即显示:
select LOG;
$| = 1; #不要讲LOG的内容保留在缓冲区,但是怎么没什么用
select STDOUT;
#.........
print LOG "This gets written to the LOG at once!\n";
重新打开标准文件句柄:
#将错误信息写到我自己的错误日志中
if(! open STDERR, ">> /home/barney/.error_log")
{
die "Can't open error log for append: $_";
}
say函数:
会在输出的时候在最后加上\n,但是需要加上use 5.010;
$str = "hello world";
say "$str";
标量变量中的文件句柄:
从perl5.6开始,已经可以把文件句柄放到标量变量中,而不必非得使用裸字,这样文件句柄就可以作为子程序的参数传递,或者放在数组,哈希表中排序或者严格控制它的作用域,但是写些应急的短小脚本,用裸字更快捷,没必要使用变量存储文件句柄。
my $rocks_fh;
open $rocks_fh, '<', '$rocks.txt'
or die "Could not open rocks.txt: $!";
防止误用:
print {$rock_fh}; #默认打印$_中的内容
print {$rocks[0]} "sandstone\n";
=cut
#!/usr/bin/perl -w
use utf8;
#use diagnostics;
#use strict;
print "hello\n";
print "world\n";
print "program name is $1\n";
while(<>) #运行程序时,perl my_program file file1
{
chomp;
print "$_\n";
}
my @strArray = ("hello\n", "world\n", "zys\n");
print @strArray, "\n";
print "@strArray";
my @items = qw(wilma dino pebbles);
my $format = "The items are:\n".("%10s\n" x @items);
printf $format, @items;
printf "The items are:\n". ("%10s\n" x @items), @items;
print "\n";
简单练习:
#!/usr/bin/perl -w
use strict;
use diagnostic;
=pod
#ex5_1
print reverse <>; #<>钻石操作符会依次存储文件中的内容翻转后输出
#运行时 perl filename.pl file1 file2 file3
=cut
=pod
print "Enter some lines, then press Ctrl-D:\n"; #或者是Ctrl-Z
chomp(my @lines = <STDIN>);
print "1234567890" x 7, "12345\n"; #标尺行,到第75个字符的地方
foreach (@lines)
{
print "%20s\n", $_;
}
my $format = "%20s\n" x @lines;
printf $format, @lines;
=cut
print "What column width would you like?"
chomp(my $width = <STDIN>);
print "Enter some lines, then press Ctrl-D:\n";#或者Ctrl-z
chomp(my @lines = <STDIN>);
print "1234567890" x (($width+9)/10), "\n"; #长度按需变化的标尺行
foreach(@lines)
{
printf "%${width}s\n", $_;
}
#printf "%*s\n", $width, $_; #*号会被$width代替