Something about Perl (3) 输入输出

    技术2022-05-11  138

    <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 标准输入 文件bettywhile (<>) {  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注意<>用于处理输入,而输入的每一行被依次放入了$_变量

    标准输出 printprint @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 八进制输出)允许使用宽度限制符 如m 将所有输出数字左补空格凑齐6位右对齐,在列对齐输出时很有用当数字本身超出宽度时显示完整数字 printf "-/n", 2e3 + 1.95;  输出2001

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

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

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

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

    FilehandlesPerl有六个特殊的filehandleSTDIN, 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也可以被重定向,这在调试中可能会有用

    打开一个Filehandleopen 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: $!";    } 


    最新回复(0)