Something about Perl (3) 输入输出

<STDIN>在foreach和while循环中的不同
在while循环中使用默认变量$_
while (<STDIN>) {
    print "I saw $_";
}
打印每条输入(包含换行符)

使用foreach循环完成同样的工作
foreach (<STDIN>) {
    print "I saw $_";
}
这里有着细微的不同,在while循环中,每次读取<STDIN>的一行,然后进入循环处理.而foreach循环中,<STDIN>被用在一个数组语境中,因此在运行循环体之前,必须读取完<STDIN>所有的内容,在处理大文件和大输入的时候,使用while能取得更好的效能(一次处理一行),因此,只要可能,就使用while,而非foreach

Diamond operater <>

对于大量Unix工具,cat或sed 使用连字符hyphen - 代表标准输入
例如:  fred- betty表示:文件fred 标准输入 文件betty
while (<>) {
  chomp;
  print "It was $_ that I saw!/n";
}
读取参数作为输入并打印
如果在运行这个程序后的参数是文件名,则会打开那个文件
如果文件名不存在,提示Can't open argv_.txt242: No such file or directory at read_by_Diamond.txt line 1
注意<>用于处理输入,而输入的每一行被依次放入了$_变量


标准输出 print
print @array; #依次打印数组中元素,不留空格
print "@array"; #依次打印数组中元素,元素之间有空格
如果@array的元素是以换行结尾的字符串,在双引号内的@array打印时还是会加上空格,看起来第一行之后的行有一个空格的缩进.最好用chomp

处理一下
print后面的参数是数组语境,使用<>用于数组语境时,得到的是一个由每行字符串组成的数组,因此可以这样使用
print <>; #与cat命令使用方式相同
print sort <>; #与sort命令使用方式相同

@ARGV 参数字符串
在程序开始之前,@ARGV数组被初始化为由参数填充的数组
<>在@ARGV中查找需要的参数,因此可以人为初始化@ARGV数组
@ARGV = qw# larry moe curly #;  #读取这三个文件,无论调用参数为何
while (<>) {
  chomp;
  print "It was $_ that I saw in some stooge-like file!/n";
}


使用printf格式化输出
语法类似于C中地printf
可用格式符 %g 输出数字,自动选择合适的表示方式,比如科学计数法
 printf "%g %g %g/n", 5/2, 51/17, 51 ** 17; 
 输出 2.5 3 1.0683e+29

%d 十进制整数输出(类似的有%x hexadecimal 16进制输出和 %o octal 八进制输出)
允许使用宽度限制符 如%6d 将所有输出数字左补空格凑齐6位右对齐,在列对齐输出时很有用
当数字本身超出宽度时显示完整数字
 printf "%2d/n", 2e3 + 1.95;
 输出2001

%s 输出字符串,也允许格式化宽度,如%10s
可以使用负数的格式符,结果类似左对齐,如
printf "%-15s/n", "flintstone";

%f 浮点输出,可以定义精度和宽度
    printf "%12f/n", 6 * 7 + 2/3;    # looks like    42.666667
    printf "%12.3f/n", 6 * 7 + 2/3;  # looks like          42.667
    printf "%12.0f/n", 6 * 7 + 2/3;  # looks like                  43

当需要输出%字符的时候使用%%
注意不是转义符/%

充分利用context可以支持任意长array的格式化输出
    my @items = qw( wilma dino pebbles );
    my $format = "The items are:/n" . ("%10s/n" x @items);
    ##注意x操作符的使用
    ## print "the format is >>$format<</n"; # for debugging
    printf $format, @items;
也可以使用更直接的方式
    printf "The items are:/n".("%10s/n" x @items), @items;
前一个@items被用于标量语境,后一个是array语境,注意区别其含义!!


Filehandles
Perl有六个特殊的filehandle
STDIN, STDOUT, STDERR, DATA, ARGV, ARGVOUT
通过> 和< 可以重定向STDIN和STDOUT
$ ./your_program <dino >wilma
这个程序以dino为输入,输出到文件wilma

Perl也可以使用在管道环境中
 $ cat fred barney | sort | ./your_program | grep something | lpr

注意默认的STDERR也是输出到屏幕,但是在管道环境中STDERR不会输出到后一个处理程序
通过使用>符号,STDERR也可以被重定向,这在调试中可能会有用

打开一个Filehandle
open CONFIG, "<conf.conf"; #读取一个文件,<是可选的,但是使用<安全性更好
open OUTPUT, ">output";    #打开文件output,先清空再写入
open APPEND, ">>appending"; #打开文件appending并追加写入
在perl 5.6之后的版本,使用
    open CONFIG, "<", "dino";
    open BEDROCK, ">", $file_name;
    open LOG, ">>", &logfile_name(  );
是好的风格,易读且当文件名中含有<或>时不会造成误解

出错处理
使用die函数在出错时终结程序运行并打印信息到STDERR
    if ( ! open LOG, ">>logfile") {
      die "Cannot create logfile: $!";
    }
其中$!变量为系统出错信息,如"permission denied"或"file not found"
仅在系统请求出错后使用$!
如果die的退出不是系统请求出错,$!的信息没有很大意义
在Windows和VMS下使用$^E可能得到更多诊断信息
die会自动给出perl程序文件名以及相应行数

warn函数与die的行为类似,唯一的不同是warn不会停止程序运行

使用filehandles
    if ( ! open PASSWD, "/etc/passwd") {
      die "How did you get logged in? ($!)";
    }
#打开文件passwd

    while (<PASSWD>) {
      chomp;
       . . .
    }
#使用<>来读取filehandle对应文件的内容

用printf或print直接写文件,如
print LOG "Captain's log, stardate 3.14159/n";  # output goes to LOG

select操作符可以重定向STDOUT,这样可以简化一些程序的书写,要记得在适当的时候把它改回来.
$|特殊变量设置为1 表示每次对select的文件输出操作后清空缓存,确保log文件能够立即得到输出项,在默认情况下输出到文件是先缓存的.

    select LOG;
    $| = 1;  # don't keep LOG entries sitting in the buffer
    select STDOUT;
    # ...time passes, babies learn to walk, tectonic plates shift, and then . . .
    print LOG "This gets written to the LOG at once!/n";

以下语句将STDERR重定向到我们指定的一个文件
   # Send errors to my private error log
    if ( ! open STDERR, ">>/home/barney/.error_log") {
      die "Can't open error log for append: $!";
    }
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值