perl的输入输出

标准输入<STDIN>

<STDIN>表示从标准输入中读取内容(来自键盘的输入),如果没有输入会继续等待,默认读取的内容会带换行符

#!/usr/bin/perl
use 5.10.1;

my $line = <STDIN>;
if($line -eq "\n")
{
    print("blank line\n");
}
else
{
    chomp($line);
    print("not blank:$line\n");
}


<STDIN>标准输入的结束表示是换行符 \n,在输入中如果发现换行符则会结束读取,换行符后面的内容不会读取,如下:

echo "hello\nworld" | perl stdin.pl

perl脚本中只会读取到 hello\n,而world 则不会读取到;

由于<STDIN>是读取标准输入,如果想用来读取文件的内容,则需要使用 shell 的重定向功能,如下所示:

perl stdin.pl <a.txt

但是上面的代码只能读取到 a.txt 的一行内容,如果要读取全部内容,需要使用 while 进行循环:

while(defined($line=<STDIN>))#推荐
{
    print("$line");
}

foreach(<STDIN>)#不推荐
{
    print("$_");
}

上面的while 循环中,每次从标准输入中读取一行并赋给变量 $line,并检查变量是否定义;也可以不将读取的内容赋给变量,此时读取内容会默认存入变量 $_中,如上面的foreach 循环中所示;

但是上面两种循环的遍历方式是有区别的,while为标量上下文,也就是每次仅仅读取文件的一行;而foreach 则是列表上下文,它首先会将文件全部读取放入一个列表,然后再在列表中每次取一个元素,foreach这种方式不推荐!!

需要注意的是,默认变量 $_ 与 <STDIN> 并没有直接的关系,只是在上面的循环体中默认将读取的内容赋给了变量 $_ 罢了;

读取文件输入<>

perl中使用两个尖括号符号来逐行读取来自文件的输入,例如从命令行传递文件作为输入源,这两个尖括号称为 钻石操作符;需要注意的是,钻石操作符也支持读取标准输入

while (defined($line = <>))
{
    print("$line");
}
#简化版
while (<>)
{
    print("$_");
}

然后在命令行中指定输入文件,这样就会依次读取文件的每一行,如下:

perl zuanshi.pl a.txt

如果想让钻石操作符在读取完输入文件后继续读取标准输入,那么只需要在命令行中加入 - 就可以了,如下:

perl zuanshi.pl a.txt -

上面的命令在用钻石操作符依次读取完 a.txt 后,然后会去读取标准输入;钻石操作符也可以依次读取打开的文件,如下:

open FILE, "a.txt"
while(defined(<FILE>))#依次读取a.txt的每一行
{
    print "$_";
}
close FILE;

chomp

前面提到过不管是 <STDIN>还是<> 在读取输入时默认都是会读取换行符的,而chomp 用于去掉字符串或者读取到的输入的一个 换行符;格式如下所示:

chomp(标量);
#不带参数的话,默认参数为默认变量$_

注意,这个函数是在原处修改字符串,但这个函数有自己的返回值:

  • 如果能去掉换行符,则返回移除的字符数,也就是数值1。这是个没什么用的返回值,因为我们都已经知道了;
  • 如果没有换行符,则返回数值0;
  • 如果结尾有两个换行符,则只去掉一个;

 一般来说,while循环中用<>或<STDIN>读取输入后(也包括open关键字打开文件再读取行的情况),第一行要做的就是去除掉行尾的换行符,所以大多采用如下的通用格式:

while (<FILE_HANDLE>)
{
    chomp;
    commands;
}

while (<STDIN>)
{
    chomp;
    commands;
}

perl的输出函数

print  say  printf  sprintf 都可以输出字符串到显示器,四个函数的应用场景不同;

print和say 的区别在于: print 不带换行,say 自带换行

printf用于格式化输出,用法与C语言相同;

对于常用的 print/say ,这里有一点需要注意:

print (3+4)*4

上面返回的是7而不是28,这是怎么计算的?

Perl中很多时候是可以省略括号的,这往往让我们忘记括号的归属,而Perl中又有上下文的概念,在不同上下文执行同一个操作的结果是不一样的

  • print不加括号的时候,它需求的参数是一个列表上下文,它后面的所有内容都会被print输出,也就是说print 后面的所有字符串都会被依次输出
  • print加括号的时候,它只会输出括号中的内容

 所以上面的语句等价于:

(print (3+4))*4

它首先执行 print(7),然后拿到print的返回值1,将其乘以4,由于没有赋值给其它变量,所以这个乘法的结果被丢弃;

另外,由于print/say不使用括号的时候,它们会输出其后面的列表,所以有以下技巧:

  • 与cat 类似,可以用 print <> 来读取并打印文件的所有内容;
  • 与 sort 类似,可以用 print sort <> 来对文件内容进行排序;

下面来看一个printf 的例子:

my @items = qw/aaa bbb ccc/;
printf "%d\n"x@items, @items;

打印结果如下:
aaa
bbb
ccc

可以看到,perl中存在和python 类似的操作,通过 x 来将字符串复制若干遍;

perl 命令行参数

perl的命令行参数默认存进数组 @ARGV 中,既然是数组,那么可以通过 $ARGV[index] 的方式访问、遍历甚至修改数组元素;如下:

perl test.pl a b c

a b c 会依次存入 ARGV[0],ARGV[1],ARGV[2]中;默认的,perl 会将这些参数视为 perl程序的数据输入源,也就是说依次将它们当成文件读取

需要区分ARGV变量和ARGV数组:

  • $ARGV 表示命令行参数列表中当前被处理的文件名
  • @ARGV 表示命令行参数数组
  • $ARGV[n] 表示命令行参数数组的元素
  • ARGV  表示<>当前正在处理的文件句柄

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值