Perl 命令行參數(shù) -p和-n
【上集回顧】:
上一次提到了-e參數(shù)皮服,一般在使用perl的單行程序時都會加上-e參數(shù)别凹。-e參數(shù)就是將后面引號內(nèi)的內(nèi)容當(dāng)作perl代碼執(zhí)行篷店。
這一次來說一說另外兩個常見的-p和-n參數(shù)砂客,這兩個參數(shù)與輸入輸出相關(guān)
簡介
-p:將參數(shù)當(dāng)作文件讀取進來挤牛,并且每次讀取一行遍歷文件预鬓,并把執(zhí)行-e參數(shù)之后的perl代碼部分得到默認(rèn)變量$_打印到標(biāo)準(zhǔn)輸出中(可以是屏幕也可以進入管道)。
-n:將參數(shù)當(dāng)作文件讀取進來赊颠,并且每次讀取一行遍歷文件格二。
兩個看起來共性有點大,那有什么區(qū)別呢竣蹦?
在之前先來看一個例子吧顶猜!
例子
首先新建一個文件 123.txt
里面的內(nèi)容為
the string is hello
the number is 12345
the float is 1.2345
我怎么知道是不是逐行讀取的呢?
在123.txt
所在位置右鍵痘括,打開git bash here
或者打開終端cd
到當(dāng)前目錄
輸入
perl -n -e '++$n;print "$n $_"' 123.txt
# 輸出為
1 the string is hello
2 the number is 12345
3 the float is 1.2345
可以看到程序部分執(zhí)行了三次长窄,文件是逐行讀取的
-p參數(shù)
- 示例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
第一行和之前的結(jié)果不一樣了
但是假如說我想的是“只要那些有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
參數(shù)不管你的代碼中有什么判斷語句來控制輸出挠日,每讀取一行都會輸出一下$_
疮绷,這個與代碼中的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
參數(shù)每次輸出的$_
的值是它從代碼執(zhí)行最后的值
再來調(diào)戲一下$_
;
- 示例4
perl -p -e 'if(m/string/){$_ = "foo\n"}' 123.txt
# 輸出為
foo
the number is 12345
the float is 1.2345
第一行已經(jīng)變了懂算,就是說$_
是可以被改變只冻,甚至改變巨大都可以
那為了剛才我們的目標(biāo),可以這樣
- 示例5
# 如果不能匹配到 string 就將變量$_設(shè)置為空字符串计技,類似于清空
perl -p -e 'if(!m/string/){$_ = ""}' 123.txt
# 輸出為
the string is hello
哈哈喜德!沒難倒我們!達到目標(biāo)了垮媒!
你有沒有感覺不太好呢舍悯!這里判斷條件倒是很簡單,所以可以這樣做睡雇,假如判斷條件多了萌衬,代碼量多了,每次都要這樣來思考不是有點不順嗎入桂?
這樣吧奄薇,開門見山驳阎,有請-n
參數(shù)登場
-n參數(shù)
先來按照-p
的路子試一試-n
- 示例6
# 我想要的是將含有string字符串的行打印出來
perl -n -e 'm/string/' 123.txt
# 輸出為:
是的抗愁,什么都沒有,的確是這樣呵晚,不是我碼字把它碼掉了.
其實有了上面的-p
的說明蜘腌,這里-n
已經(jīng)比較明確了,它其他方面的和-p
一樣饵隙,但是他不會輸出$_
撮珠,也就是說程序默認(rèn)不會輸出任何東西(當(dāng)然不包括錯誤信息在內(nèi))
于是上面的問題就可以這樣解了
- 示例7
perl -n -e 'if(m/string/){print $_}' 123.txt
輸出為:
the string is hello
到了這里大家應(yīng)該明白了-p和-n的區(qū)別,其實對于命令行來說金矛,-p和-n用的都挺多的芯急,就看你需要什么,怎么做起來更快驶俊,就選哪一個娶耍。
問題
- 假如我讀取文件不想要后面的換行符出現(xiàn),輸出的時候我自己加換行符饼酿,怎么做榕酒?
答:其實和寫perl腳本一樣胚膊,其實可以這樣做
perl -n -e 'chomp;if(/string/){print "$_\n"}' 123.txt
也就是加一個chomp;
其實除了這種方式,還有一種加上參數(shù)-l
可以達到先自動chomp
想鹰,之后自動在$_
后面加上\n
然后輸出
- 這個-p和-n參數(shù)的每行讀取文件怎么和那個鉆石操作符
<>
一樣拔赏瘛!
答:的確是這樣的
# 平常寫perl腳本我們一般寫
open READ,"<","123.txt" or die "$!";
while(< READ >){
..........;
}
# 對于單行程序直接就是
perl -n -e '........' 123.txt
這樣看來單行程序在寫較短程序上比直接去寫perl腳本來的快辑舷,來的節(jié)省
在這里再引申一下
如果我有一個fasta文件喻犁,假設(shè)名稱為fasta.fasta 內(nèi)容為
>cox1
ATGCGATCGTAGCATGCTAGCTACG
ACAAGCTAGCTAGCTAGCAGCATCT
ACGTGCAT
>rpl10
ATGAGCTAGCTAGCTAGACGTACGT
ACGTAG
# 假如在命令行中這樣輸入
perl -p -e 'if(/^>/){$_ = <> || ""}' fasta.fasta
# 輸出為
ATGCGATCGTAGCATGCTAGCTACG
ACAAGCTAGCTAGCTAGCAGCATCT
ACGTGCAT
ATGAGCTAGCTAGCTAGACGTACGT
ACGTAG
- 為什么我一直沒有輸出啊惩妇!
你是不是把參數(shù)順序?qū)懛戳?/p>
- 錯誤寫法
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
第三種情況雖然兩個參數(shù)并在一起寫了株汉,可是有先后順序,其實第三種就是第一種的寫法歌殃。也就是說引號對引起來的代碼需要靠近-e乔妈,而且-e參數(shù)一般放在所有參數(shù)最后一個
perl讀取文件的方式
- 放在命令行代碼塊的末尾
perl -n -e 'print $_' 123.txt
- 結(jié)合Linux工具
cat 123.txt | perl -n -e 'print $_'
- 使用文件句柄
perl -e '
open FILE,"<","123.txt" or die $!;
while(<FILE>){
print $_;
}
'
版權(quán)聲明:本文采用 知識共享署名-非商業(yè)性使用-禁止演繹 4.0 國際許可協(xié)議 (CC BY-NC-ND 4.0) 進行許可。