perl 运行linux命令行参数,Perl One-Liners | Perl命令行学习2 -p和-n参数

Perl 命令行参数 -p和-n

【上集回顾】:

上一次提到了-e参数,一般在使用perl的单行程序时都会加上-e参数。-e参数就是将后面引号内的内容当作perl代码执行。

这一次来说一说另外两个常见的-p和-n参数,这两个参数与输入输出相关

简介

-p:将参数当作文件读取进来,并且每次读取一行遍历文件,并把执行-e参数之后的perl代码部分得到默认变量$_打印到标准输出中(可以是屏幕也可以进入管道)。

-n:将参数当作文件读取进来,并且每次读取一行遍历文件。

两个看起来共性有点大,那有什么区别呢?

在之前先来看一个例子吧!

例子

首先新建一个文件 123.txt

里面的内容为

the string is hello

the number is 12345

the float is 1.2345

我怎么知道是不是逐行读取的呢?

在123.txt所在位置右键,打开git bash here或者打开终端cd到当前目录

输入

perl -n -e '++$n;print "$n $_"' 123.txt

# 输出为

1 the string is hello

2 the number is 12345

3 the float is 1.2345

可以看到程序部分执行了三次,文件是逐行读取的

-p参数

示例1

# 比如我想让含有字符串string的行打印出来

perl -p -e 'm/string/' 123.txt

# 输出为

the string is hello

the number is 12345

the float is 1.2345

可以看到和原来的文件是没有什么两样的

示例1.1

perl -p -e 's/string/number/' 123.txt

# 输出

the number is hello

the number is 12345

the float is 1.2345

第一行和之前的结果不一样了

但是假如说我想的是“只要那些有string这样字眼的行输出出来呢”?

于是我就想可不可以这样写:

示例2

perl -p -e 'if(m/string/){print $_}' 123.txt

# 输出为

the string is hello

the string is hello

the number is 12345

the float is 1.2345

可以看到文件第一行输出了两次,也就是说

-p参数不管你的代码中有什么判断语句来控制输出,每读取一行都会输出一下$_,这个与代码中的print不会合并,它不管究竟有没有print

那它是输出的什么呢,输出什么时候的$_呢?

来这样玩一下

示例3

perl -p -e 's/string/number/;s/hello/world/' 123.txt

# 输出为

the number is world

the number is 12345

the float is 1.2345

传进来文件第一行的变量$_在perl代码中其实变换了两次

最开始时候:the string is hello

第一次变换:the number is hello

第二次变化:the number is world

可以看到,-p参数每次输出的$_的值是它从代码执行最后的值

再来调戏一下$_;

示例4

perl -p -e 'if(m/string/){$_ = "foo\n"}' 123.txt

# 输出为

foo

the number is 12345

the float is 1.2345

第一行已经变了,就是说$_是可以被改变,甚至改变巨大都可以

那为了刚才我们的目标,可以这样

示例5

# 如果不能匹配到 string 就将变量$_设置为空字符串,类似于清空

perl -p -e 'if(!m/string/){$_ = ""}' 123.txt

# 输出为

the string is hello

哈哈!没难倒我们!达到目标了!

你有没有感觉不太好呢!这里判断条件倒是很简单,所以可以这样做,假如判断条件多了,代码量多了,每次都要这样来思考不是有点不顺吗?

这样吧,开门见山,有请-n参数登场

-n参数

先来按照-p的路子试一试-n

示例6

# 我想要的是将含有string字符串的行打印出来

perl -n -e 'm/string/' 123.txt

# 输出为:

是的,什么都没有,的确是这样,不是我码字把它码掉了.

其实有了上面的-p的说明,这里-n已经比较明确了,它其他方面的和-p一样,但是他不会输出$_,也就是说程序默认不会输出任何东西(当然不包括错误信息在内)

于是上面的问题就可以这样解了

示例7

perl -n -e 'if(m/string/){print $_}' 123.txt

输出为:

the string is hello

到了这里大家应该明白了-p和-n的区别,其实对于命令行来说,-p和-n用的都挺多的,就看你需要什么,怎么做起来更快,就选哪一个。

问题

假如我读取文件不想要后面的换行符出现,输出的时候我自己加换行符,怎么做?

答:其实和写perl脚本一样,其实可以这样做

perl -n -e 'chomp;if(/string/){print "$_\n"}' 123.txt

也就是加一个chomp;

其实除了这种方式,还有一种加上参数-l可以达到先自动chomp,之后自动在$_后面加上\n然后输出

这个-p和-n参数的每行读取文件怎么和那个钻石操作符<>一样啊!

答:的确是这样的

# 平常写perl脚本我们一般写

open READ,"

while(< READ >){

..........;

}

# 对于单行程序直接就是

perl -n -e '........' 123.txt

这样看来单行程序在写较短程序上比直接去写perl脚本来的快,来的节省

在这里再引申一下

如果我有一个fasta文件,假设名称为fasta.fasta 内容为

>cox1

ATGCGATCGTAGCATGCTAGCTACG

ACAAGCTAGCTAGCTAGCAGCATCT

ACGTGCAT

>rpl10

ATGAGCTAGCTAGCTAGACGTACGT

ACGTAG

# 假如在命令行中这样输入

perl -p -e 'if(/^>/){$_ = <> || ""}' fasta.fasta

# 输出为

ATGCGATCGTAGCATGCTAGCTACG

ACAAGCTAGCTAGCTAGCAGCATCT

ACGTGCAT

ATGAGCTAGCTAGCTAGACGTACGT

ACGTAG

为什么我一直没有输出啊!

你是不是把参数顺序写反了

错误写法

perl -e -p 'print if /string/' 123.txt

perl -e -n 'print if /string/' 123.txt

perl -ep 'print if /string/' 123.txt

正确写法

perl -p -e 'print if /string/' 123.txt

perl -pe 'print if /string/' 123.txt

第三种情况虽然两个参数并在一起写了,可是有先后顺序,其实第三种就是第一种的写法。也就是说引号对引起来的代码需要靠近-e,而且-e参数一般放在所有参数最后一个

perl读取文件的方式

放在命令行代码块的末尾

perl -n -e 'print $_' 123.txt

结合Linux工具

cat 123.txt | perl -n -e 'print $_'

使用文件句柄

perl -e '

open FILE,"

while(){

print $_;

}

'

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值